mir-opt: Eliminate trivial unnecessary storage annotations

This commit is contained in:
dianqk 2025-07-15 22:54:54 +08:00
parent cc93132ae4
commit 85b2f70693
No known key found for this signature in database
50 changed files with 179 additions and 556 deletions

View file

@ -30,16 +30,10 @@ impl<'tcx> Statement<'tcx> {
}
let replaced_stmt = std::mem::replace(&mut self.kind, StatementKind::Nop);
if !drop_debuginfo {
match replaced_stmt {
StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place)))
if let Some(local) = place.as_local() =>
{
self.debuginfos.push(StmtDebugInfo::AssignRef(local, ref_place));
}
_ => {
bug!("debuginfo is not yet supported.")
}
}
let Some(debuginfo) = replaced_stmt.as_debuginfo() else {
bug!("debuginfo is not yet supported.")
};
self.debuginfos.push(debuginfo);
}
}

View file

@ -233,8 +233,10 @@ impl<'a> MaybeTransitiveLiveLocals<'a> {
// Compute the place that we are storing to, if any
let destination = match stmt_kind {
StatementKind::Assign(box (place, rvalue)) => (rvalue.is_safe_to_remove()
// FIXME: We are not sure how we should represent this debugging information for some statements,
// keep it for now.
&& (!debuginfo_locals.contains(place.local)
|| (place.as_local().is_some() && matches!(rvalue, mir::Rvalue::Ref(..)))))
|| (place.as_local().is_some() && stmt_kind.as_debuginfo().is_some())))
.then_some(*place),
StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => {
(!debuginfo_locals.contains(place.local)).then_some(**place)

View file

@ -22,13 +22,15 @@ use rustc_mir_dataflow::impls::{
LivenessTransferFunction, MaybeTransitiveLiveLocals, borrowed_locals,
};
use crate::simplify::UsedInStmtLocals;
use crate::util::is_within_packed;
/// Performs the optimization on the body
///
/// The `borrowed` set must be a `DenseBitSet` of all the locals that are ever borrowed in this
/// body. It can be generated via the [`borrowed_locals`] function.
fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
/// Returns true if any instruction is eliminated.
fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
let borrowed_locals = borrowed_locals(body);
// If the user requests complete debuginfo, mark the locals that appear in it as live, so
@ -97,8 +99,9 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
}
if patch.is_empty() && call_operands_to_move.is_empty() {
return;
return false;
}
let eliminated = !patch.is_empty();
let bbs = body.basic_blocks.as_mut_preserves_cfg();
for (Location { block, statement_index }, drop_debuginfo) in patch {
@ -112,6 +115,8 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let Operand::Copy(place) = *arg else { bug!() };
*arg = Operand::Move(place);
}
eliminated
}
pub(super) enum DeadStoreElimination {
@ -132,7 +137,12 @@ impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
}
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
eliminate(tcx, body);
if eliminate(tcx, body) {
UsedInStmtLocals::new(body).remove_unused_storage_annotations(body);
for data in body.basic_blocks.as_mut_preserves_cfg() {
data.strip_nops();
}
}
}
fn is_required(&self) -> bool {

View file

@ -21,7 +21,7 @@ use tracing::{debug, instrument, trace, trace_span};
use crate::cost_checker::{CostChecker, is_call_like};
use crate::deref_separator::deref_finder;
use crate::simplify::simplify_cfg;
use crate::simplify::{UsedInStmtLocals, simplify_cfg};
use crate::validate::validate_types;
use crate::{check_inline, util};
@ -935,7 +935,7 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
in_cleanup_block: false,
return_block,
tcx,
always_live_locals: DenseBitSet::new_filled(callee_body.local_decls.len()),
always_live_locals: UsedInStmtLocals::new(&callee_body).locals,
};
// Map all `Local`s, `SourceScope`s and `BasicBlock`s to new ones
@ -995,6 +995,10 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
// people working on rust can build with or without debuginfo while
// still getting consistent results from the mir-opt tests.
caller_body.var_debug_info.append(&mut callee_body.var_debug_info);
} else {
for bb in callee_body.basic_blocks_mut() {
bb.drop_debuginfo();
}
}
caller_body.basic_blocks_mut().append(callee_body.basic_blocks_mut());

View file

@ -35,12 +35,12 @@
//! pre-"runtime" MIR!
use itertools::Itertools as _;
use rustc_index::bit_set::DenseBitSet;
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_middle::mir::visit::{
MutVisitor, MutatingUseContext, NonUseContext, PlaceContext, Visitor,
};
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use rustc_mir_dataflow::debuginfo::debuginfo_locals;
use rustc_span::DUMMY_SP;
use smallvec::SmallVec;
use tracing::{debug, trace};
@ -329,7 +329,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
fn strip_nops(&mut self) {
for blk in self.basic_blocks.iter_mut() {
blk.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop))
blk.strip_nops();
}
}
}
@ -502,17 +502,22 @@ fn make_local_map<V>(
/// Keeps track of used & unused locals.
struct UsedLocals {
increment: bool,
arg_count: u32,
use_count: IndexVec<Local, u32>,
always_used: DenseBitSet<Local>,
}
impl UsedLocals {
/// Determines which locals are used & unused in the given body.
fn new(body: &Body<'_>) -> Self {
let mut always_used = debuginfo_locals(body);
always_used.insert(RETURN_PLACE);
for arg in body.args_iter() {
always_used.insert(arg);
}
let mut this = Self {
increment: true,
arg_count: body.arg_count.try_into().unwrap(),
use_count: IndexVec::from_elem(0, &body.local_decls),
always_used,
};
this.visit_body(body);
this
@ -520,10 +525,16 @@ impl UsedLocals {
/// Checks if local is used.
///
/// Return place and arguments are always considered used.
/// Return place, arguments, var debuginfo are always considered used.
fn is_used(&self, local: Local) -> bool {
trace!("is_used({:?}): use_count: {:?}", local, self.use_count[local]);
local.as_u32() <= self.arg_count || self.use_count[local] != 0
trace!(
"is_used({:?}): use_count: {:?}, always_used: {}",
local,
self.use_count[local],
self.always_used.contains(local)
);
// To keep things simple, we don't handle debugging information here, these are in DSE.
self.always_used.contains(local) || self.use_count[local] != 0
}
/// Updates the use counts to reflect the removal of given statement.
@ -568,17 +579,9 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
StatementKind::ConstEvalCounter
| StatementKind::Nop
| StatementKind::StorageLive(..)
| StatementKind::StorageDead(..) => {
for debuginfo in statement.debuginfos.iter() {
self.visit_statement_debuginfo(debuginfo, location);
}
}
| StatementKind::StorageDead(..) => {}
StatementKind::Assign(box (ref place, ref rvalue)) => {
if rvalue.is_safe_to_remove() {
for debuginfo in statement.debuginfos.iter() {
self.visit_statement_debuginfo(debuginfo, location);
}
self.visit_lhs(place, location);
self.visit_rvalue(rvalue, location);
} else {
@ -589,18 +592,18 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
StatementKind::SetDiscriminant { ref place, variant_index: _ }
| StatementKind::Deinit(ref place)
| StatementKind::BackwardIncompatibleDropHint { ref place, reason: _ } => {
for debuginfo in statement.debuginfos.iter() {
self.visit_statement_debuginfo(debuginfo, location);
}
self.visit_lhs(place, location);
}
}
}
fn visit_local(&mut self, local: Local, ctx: PlaceContext, _location: Location) {
if matches!(ctx, PlaceContext::NonUse(_)) {
return;
}
if self.increment {
self.use_count[local] += 1;
} else if ctx != PlaceContext::NonUse(NonUseContext::VarDebugInfo) {
} else {
assert_ne!(self.use_count[local], 0);
self.use_count[local] -= 1;
}
@ -620,28 +623,26 @@ fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Bod
for data in body.basic_blocks.as_mut_preserves_cfg() {
// Remove unnecessary StorageLive and StorageDead annotations.
data.retain_statements(|statement| {
let keep = match &statement.kind {
for statement in data.statements.iter_mut() {
let keep_statement = match &statement.kind {
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
used_locals.is_used(*local)
}
StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local),
StatementKind::SetDiscriminant { place, .. }
| StatementKind::BackwardIncompatibleDropHint { place, reason: _ }
| StatementKind::Deinit(place) => used_locals.is_used(place.local),
StatementKind::Nop => false,
_ => true,
StatementKind::Assign(box (place, _))
| StatementKind::SetDiscriminant { box place, .. }
| StatementKind::BackwardIncompatibleDropHint { box place, .. }
| StatementKind::Deinit(box place) => used_locals.is_used(place.local),
_ => continue,
};
if !keep {
trace!("removing statement {:?}", statement);
modified = true;
used_locals.statement_removed(statement);
if keep_statement {
continue;
}
keep
});
trace!("removing statement {:?}", statement);
modified = true;
used_locals.statement_removed(statement);
statement.make_nop(true);
}
data.strip_nops();
}
}
}
@ -660,3 +661,42 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {
*l = self.map[*l].unwrap();
}
}
pub(crate) struct UsedInStmtLocals {
pub(crate) locals: DenseBitSet<Local>,
}
impl UsedInStmtLocals {
pub(crate) fn new(body: &Body<'_>) -> Self {
let mut this = Self { locals: DenseBitSet::new_empty(body.local_decls.len()) };
this.visit_body(body);
this
}
pub(crate) fn remove_unused_storage_annotations<'tcx>(&self, body: &mut Body<'tcx>) {
for data in body.basic_blocks.as_mut_preserves_cfg() {
// Remove unnecessary StorageLive and StorageDead annotations.
for statement in data.statements.iter_mut() {
let keep_statement = match &statement.kind {
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
self.locals.contains(*local)
}
_ => continue,
};
if keep_statement {
continue;
}
statement.make_nop(true);
}
}
}
}
impl<'tcx> Visitor<'tcx> for UsedInStmtLocals {
fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
if matches!(context, PlaceContext::NonUse(_)) {
return;
}
self.locals.insert(local);
}
}

View file

@ -19,10 +19,6 @@
- _3 = copy _2;
- _2 = copy _1;
- _1 = copy _5;
+ nop;
+ nop;
+ nop;
+ nop;
_4 = cond() -> [return: bb1, unwind continue];
}

View file

@ -15,7 +15,6 @@
StorageLive(_2);
- _2 = &((*_1).2: i32);
+ // DBG: _2 = &((*_1).2: i32);
+ nop;
StorageLive(_3);
StorageLive(_4);
_4 = &((*_1).0: i32);

View file

@ -12,14 +12,13 @@
}
bb0: {
StorageLive(_2);
- StorageLive(_2);
_3 = deref_copy (_1.1: &Foo);
- _2 = &((*_3).2: i32);
+ // DBG: _2 = &((*_3).2: i32);
+ nop;
_4 = deref_copy (_1.1: &Foo);
_0 = copy ((*_4).0: i32);
StorageDead(_2);
- StorageDead(_2);
return;
}
}

View file

@ -14,13 +14,11 @@
-
- bb1: {
- // DBG: _3 = &((*_1).0: i32);
- nop;
- goto -> bb2;
- }
-
- bb2: {
// DBG: _4 = &((*_1).1: i64);
- nop;
_0 = copy ((*_1).2: i32);
return;
}

View file

@ -17,16 +17,13 @@
- bb1: {
(*_2) = const true;
// DBG: _3 = &((*_1).0: i32);
- nop;
- goto -> bb2;
- }
-
- bb2: {
// DBG: _4 = &((*_1).1: i64);
- nop;
_0 = copy ((*_1).2: i32);
// DBG: _5 = &((*_1).2: i32);
- nop;
return;
}
}

View file

@ -16,16 +16,13 @@
-
- bb1: {
// DBG: _2 = &((*_1).0: i32);
- nop;
- goto -> bb2;
- }
-
- bb2: {
// DBG: _3 = &((*_1).1: i64);
- nop;
_0 = copy ((*_1).2: i32);
// DBG: _4 = &((*_1).2: i32);
- nop;
return;
}
}

View file

@ -17,13 +17,11 @@
bb1: {
- // DBG: _3 = &((*_1).0: i32);
- nop;
- goto -> bb3;
- }
-
- bb2: {
// DBG: _4 = &((*_1).1: i64);
- nop;
_0 = copy ((*_1).2: i32);
return;
}
@ -32,7 +30,6 @@
+ bb2: {
+ // DBG: _3 = &((*_1).0: i32);
// DBG: _5 = &((*_1).2: i32);
- nop;
_0 = copy ((*_1).0: i32);
return;
}

View file

@ -16,16 +16,13 @@
-
- bb1: {
// DBG: _3 = &((*_1).0: i32);
- nop;
- goto -> bb2;
- }
-
- bb2: {
// DBG: _4 = &((*_1).1: i64);
- nop;
_0 = copy ((*_1).2: i32);
// DBG: _5 = &((*_1).2: i32);
- nop;
return;
}
}

View file

@ -64,9 +64,7 @@
+ StorageLive(_8);
+ StorageLive(_9);
+ StorageLive(_11);
+ // DBG: _11 = &((*_6).0: alloc::raw_vec::RawVec<A>);
+ StorageLive(_12);
+ // DBG: _12 = &(((*_6).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner);
+ StorageLive(_13);
+ _13 = copy (((((*_6).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
+ _9 = copy _13 as *mut A (Transmute);
@ -92,7 +90,6 @@
_5 = copy _2;
- _0 = drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind unreachable];
+ StorageLive(_17);
+ StorageLive(_18);
+ _17 = discriminant((*_5));
+ switchInt(move _17) -> [0: bb5, otherwise: bb6];
}
@ -118,7 +115,6 @@
+ }
+
+ bb5: {
+ StorageDead(_18);
+ StorageDead(_17);
StorageDead(_5);
return;

View file

@ -27,13 +27,11 @@
_5 = copy _2;
- _0 = drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind continue];
+ StorageLive(_6);
+ StorageLive(_7);
+ _6 = discriminant((*_5));
+ switchInt(move _6) -> [0: bb2, otherwise: bb3];
}
bb2: {
+ StorageDead(_7);
+ StorageDead(_6);
StorageDead(_5);
return;

View file

@ -129,11 +129,8 @@
_10 = deref_copy (_1.1: &mut std::task::Context<'_>);
_9 = &mut (*_10);
- _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind unreachable];
+ StorageLive(_11);
+ StorageLive(_15);
+ StorageLive(_16);
+ StorageLive(_25);
+ StorageLive(_27);
+ StorageLive(_30);
+ StorageLive(_31);
+ StorageLive(_32);
@ -166,11 +163,8 @@
+ StorageDead(_32);
+ StorageDead(_31);
+ StorageDead(_30);
+ StorageDead(_27);
+ StorageDead(_25);
+ StorageDead(_16);
+ StorageDead(_15);
+ StorageDead(_11);
StorageDead(_9);
StorageDead(_8);
StorageDead(_7);
@ -223,17 +217,13 @@
+ _22 = &mut (*_23);
+ StorageDead(_24);
+ StorageLive(_44);
+ StorageLive(_45);
+ StorageLive(_49);
+ StorageLive(_41);
+ StorageLive(_42);
+ StorageLive(_43);
+ // DBG: _45 = &_19;
+ StorageLive(_46);
+ // DBG: _46 = &(_19.0: &mut std::future::Ready<()>);
+ _44 = copy (_19.0: &mut std::future::Ready<()>);
+ StorageDead(_46);
+ // DBG: _43 = &((*_44).0: std::option::Option<()>);
+ StorageLive(_47);
+ _47 = Option::<()>::None;
+ _42 = copy ((*_44).0: std::option::Option<()>);
@ -315,7 +305,6 @@
+ _18 = Poll::<()>::Ready(move _41);
+ StorageDead(_41);
+ StorageDead(_49);
+ StorageDead(_45);
+ StorageDead(_44);
+ StorageDead(_22);
+ StorageDead(_19);

View file

@ -131,11 +131,8 @@
_10 = deref_copy (_1.1: &mut std::task::Context<'_>);
_9 = &mut (*_10);
- _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind: bb5];
+ StorageLive(_11);
+ StorageLive(_15);
+ StorageLive(_16);
+ StorageLive(_25);
+ StorageLive(_27);
+ StorageLive(_30);
+ StorageLive(_31);
+ StorageLive(_32);
@ -180,11 +177,8 @@
+ StorageDead(_32);
+ StorageDead(_31);
+ StorageDead(_30);
+ StorageDead(_27);
+ StorageDead(_25);
+ StorageDead(_16);
+ StorageDead(_15);
+ StorageDead(_11);
StorageDead(_9);
StorageDead(_8);
StorageDead(_7);
@ -240,17 +234,13 @@
+ _22 = &mut (*_23);
+ StorageDead(_24);
+ StorageLive(_46);
+ StorageLive(_47);
+ StorageLive(_51);
+ StorageLive(_43);
+ StorageLive(_44);
+ StorageLive(_45);
+ // DBG: _47 = &_19;
+ StorageLive(_48);
+ // DBG: _48 = &(_19.0: &mut std::future::Ready<()>);
+ _46 = copy (_19.0: &mut std::future::Ready<()>);
+ StorageDead(_48);
+ // DBG: _45 = &((*_46).0: std::option::Option<()>);
+ StorageLive(_49);
+ _49 = Option::<()>::None;
+ _44 = copy ((*_46).0: std::option::Option<()>);
@ -356,7 +346,6 @@
+ _18 = Poll::<()>::Ready(move _43);
+ StorageDead(_43);
+ StorageDead(_51);
+ StorageDead(_47);
+ StorageDead(_46);
+ StorageDead(_22);
+ StorageDead(_19);

View file

@ -30,7 +30,6 @@
StorageLive(_4);
StorageLive(_5);
_5 = copy _1;
nop;
- StorageLive(_14);
- _14 = BitAnd(copy _5, const 255_u32);
- _4 = BitOr(const 0_u32, move _14);

View file

@ -30,7 +30,6 @@
StorageLive(_4);
StorageLive(_5);
_5 = copy _1;
nop;
- StorageLive(_14);
- _14 = BitAnd(copy _5, const 255_u32);
- _4 = BitOr(const 0_u32, move _14);

View file

@ -33,15 +33,9 @@
}
bb2: {
StorageLive(_5);
// DBG: _5 = &(*_2)[0 of 3];
StorageLive(_6);
// DBG: _6 = &(*_2)[1 of 3];
StorageLive(_7);
// DBG: _7 = &(*_2)[2 of 3];
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageDead(_4);
return;
}

View file

@ -33,15 +33,9 @@
}
bb2: {
StorageLive(_5);
// DBG: _5 = &(*_2)[0 of 3];
StorageLive(_6);
// DBG: _6 = &(*_2)[1 of 3];
StorageLive(_7);
// DBG: _7 = &(*_2)[2 of 3];
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageDead(_4);
return;
}

View file

@ -6,7 +6,6 @@ fn num_to_digit(_1: char) -> u32 {
let mut _4: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
let _2: std::option::Option<u32>;
let mut _7: &std::option::Option<u32>;
scope 2 (inlined Option::<u32>::is_some) {
let mut _3: isize;
scope 3 {
@ -21,17 +20,14 @@ fn num_to_digit(_1: char) -> u32 {
}
bb0: {
StorageLive(_7);
StorageLive(_2);
_2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable];
}
bb1: {
// DBG: _7 = &_2;
StorageLive(_3);
_3 = discriminant(_2);
StorageDead(_2);
StorageDead(_7);
switchInt(move _3) -> [1: bb2, otherwise: bb7];
}

View file

@ -6,7 +6,6 @@ fn num_to_digit(_1: char) -> u32 {
let mut _4: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
let _2: std::option::Option<u32>;
let mut _7: &std::option::Option<u32>;
scope 2 (inlined Option::<u32>::is_some) {
let mut _3: isize;
scope 3 {
@ -21,17 +20,14 @@ fn num_to_digit(_1: char) -> u32 {
}
bb0: {
StorageLive(_7);
StorageLive(_2);
_2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue];
}
bb1: {
// DBG: _7 = &_2;
StorageLive(_3);
_3 = discriminant(_2);
StorageDead(_2);
StorageDead(_7);
switchInt(move _3) -> [1: bb2, otherwise: bb7];
}

View file

@ -6,7 +6,6 @@ fn num_to_digit(_1: char) -> u32 {
let mut _4: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
let _2: std::option::Option<u32>;
let mut _7: &std::option::Option<u32>;
scope 2 (inlined Option::<u32>::is_some) {
let mut _3: isize;
scope 3 {
@ -21,17 +20,14 @@ fn num_to_digit(_1: char) -> u32 {
}
bb0: {
StorageLive(_7);
StorageLive(_2);
_2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable];
}
bb1: {
// DBG: _7 = &_2;
StorageLive(_3);
_3 = discriminant(_2);
StorageDead(_2);
StorageDead(_7);
switchInt(move _3) -> [1: bb2, otherwise: bb7];
}

View file

@ -6,7 +6,6 @@ fn num_to_digit(_1: char) -> u32 {
let mut _4: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
let _2: std::option::Option<u32>;
let mut _7: &std::option::Option<u32>;
scope 2 (inlined Option::<u32>::is_some) {
let mut _3: isize;
scope 3 {
@ -21,17 +20,14 @@ fn num_to_digit(_1: char) -> u32 {
}
bb0: {
StorageLive(_7);
StorageLive(_2);
_2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue];
}
bb1: {
// DBG: _7 = &_2;
StorageLive(_3);
_3 = discriminant(_2);
StorageDead(_2);
StorageDead(_7);
switchInt(move _3) -> [1: bb2, otherwise: bb7];
}

View file

@ -5,9 +5,7 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
debug n => _2;
let mut _0: u16;
scope 1 (inlined <u16 as Step>::forward) {
let _8: std::option::Option<u16>;
let mut _10: u16;
let mut _11: &std::option::Option<u16>;
let mut _8: u16;
scope 2 {
}
scope 3 (inlined <u16 as Step>::forward_checked) {
@ -15,9 +13,8 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
scope 6 (inlined core::num::<impl u16>::checked_add) {
let mut _5: (u16, bool);
let mut _6: bool;
let mut _7: u16;
scope 7 (inlined std::intrinsics::unlikely) {
let _9: ();
let _7: ();
}
}
}
@ -38,8 +35,6 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
bb0: {
StorageLive(_4);
StorageLive(_11);
StorageLive(_8);
StorageLive(_3);
_3 = Gt(copy _2, const 65535_usize);
switchInt(move _3) -> [0: bb1, otherwise: bb5];
@ -58,55 +53,34 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
bb2: {
StorageDead(_5);
StorageDead(_6);
StorageLive(_7);
_7 = AddUnchecked(copy _1, copy _4);
_8 = Option::<u16>::Some(move _7);
StorageDead(_7);
// DBG: _11 = &_8;
StorageDead(_8);
StorageDead(_11);
goto -> bb7;
}
bb3: {
_9 = std::intrinsics::cold_path() -> [return: bb4, unwind unreachable];
_7 = std::intrinsics::cold_path() -> [return: bb4, unwind unreachable];
}
bb4: {
StorageDead(_5);
StorageDead(_6);
_8 = const Option::<u16>::None;
// DBG: _11 = &_8;
goto -> bb6;
}
bb5: {
StorageDead(_3);
_8 = const Option::<u16>::None;
// DBG: _11 = &_8;
goto -> bb6;
}
bb6: {
StorageDead(_8);
StorageDead(_11);
assert(!const true, "attempt to compute `{} + {}`, which would overflow", const core::num::<impl u16>::MAX, const 1_u16) -> [success: bb7, unwind unreachable];
}
bb7: {
StorageLive(_10);
_10 = copy _2 as u16 (IntToInt);
_0 = Add(copy _1, copy _10);
StorageDead(_10);
StorageLive(_8);
_8 = copy _2 as u16 (IntToInt);
_0 = Add(copy _1, copy _8);
StorageDead(_8);
StorageDead(_4);
return;
}
}
ALLOC0 (size: 4, align: 2) {
00 00 __ __ ..
}
ALLOC1 (size: 4, align: 2) {
00 00 __ __ ..
}

View file

@ -5,9 +5,7 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
debug n => _2;
let mut _0: u16;
scope 1 (inlined <u16 as Step>::forward) {
let _8: std::option::Option<u16>;
let mut _10: u16;
let mut _11: &std::option::Option<u16>;
let mut _8: u16;
scope 2 {
}
scope 3 (inlined <u16 as Step>::forward_checked) {
@ -15,9 +13,8 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
scope 6 (inlined core::num::<impl u16>::checked_add) {
let mut _5: (u16, bool);
let mut _6: bool;
let mut _7: u16;
scope 7 (inlined std::intrinsics::unlikely) {
let _9: ();
let _7: ();
}
}
}
@ -38,8 +35,6 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
bb0: {
StorageLive(_4);
StorageLive(_11);
StorageLive(_8);
StorageLive(_3);
_3 = Gt(copy _2, const 65535_usize);
switchInt(move _3) -> [0: bb1, otherwise: bb5];
@ -58,55 +53,34 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
bb2: {
StorageDead(_5);
StorageDead(_6);
StorageLive(_7);
_7 = AddUnchecked(copy _1, copy _4);
_8 = Option::<u16>::Some(move _7);
StorageDead(_7);
// DBG: _11 = &_8;
StorageDead(_8);
StorageDead(_11);
goto -> bb7;
}
bb3: {
_9 = std::intrinsics::cold_path() -> [return: bb4, unwind unreachable];
_7 = std::intrinsics::cold_path() -> [return: bb4, unwind unreachable];
}
bb4: {
StorageDead(_5);
StorageDead(_6);
_8 = const Option::<u16>::None;
// DBG: _11 = &_8;
goto -> bb6;
}
bb5: {
StorageDead(_3);
_8 = const Option::<u16>::None;
// DBG: _11 = &_8;
goto -> bb6;
}
bb6: {
StorageDead(_8);
StorageDead(_11);
assert(!const true, "attempt to compute `{} + {}`, which would overflow", const core::num::<impl u16>::MAX, const 1_u16) -> [success: bb7, unwind continue];
}
bb7: {
StorageLive(_10);
_10 = copy _2 as u16 (IntToInt);
_0 = Add(copy _1, copy _10);
StorageDead(_10);
StorageLive(_8);
_8 = copy _2 as u16 (IntToInt);
_0 = Add(copy _1, copy _8);
StorageDead(_8);
StorageDead(_4);
return;
}
}
ALLOC0 (size: 4, align: 2) {
00 00 __ __ ..
}
ALLOC1 (size: 4, align: 2) {
00 00 __ __ ..
}

View file

@ -12,10 +12,8 @@ fn clone_as_copy(_1: &NestCopy) -> NestCopy {
}
bb0: {
StorageLive(_2);
// DBG: _2 = &((*_1).1: AllCopy);
_0 = copy (*_1);
StorageDead(_2);
return;
}
}

View file

@ -5,58 +5,28 @@ fn enum_clone_as_copy(_1: &Enum1) -> Enum1 {
let mut _0: Enum1;
scope 1 (inlined <Enum1 as Clone>::clone) {
debug self => _1;
let mut _2: isize;
let _3: &AllCopy;
let _4: &NestCopy;
let _2: &AllCopy;
let _3: &NestCopy;
scope 2 {
debug __self_0 => _3;
debug __self_0 => _2;
scope 6 (inlined <AllCopy as Clone>::clone) {
debug self => _3;
debug self => _2;
}
}
scope 3 {
debug __self_0 => _4;
debug __self_0 => _3;
scope 4 (inlined <NestCopy as Clone>::clone) {
debug self => _4;
let _5: &AllCopy;
debug self => _3;
let _4: &AllCopy;
scope 5 (inlined <AllCopy as Clone>::clone) {
debug self => _5;
debug self => _4;
}
}
}
}
bb0: {
StorageLive(_2);
StorageLive(_3);
StorageLive(_4);
_2 = discriminant((*_1));
switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4];
}
bb1: {
// DBG: _3 = &(((*_1) as A).0: AllCopy);
_0 = copy (*_1);
goto -> bb3;
}
bb2: {
// DBG: _4 = &(((*_1) as B).0: NestCopy);
StorageLive(_5);
// DBG: _5 = &((((*_1) as B).0: NestCopy).1: AllCopy);
StorageDead(_5);
_0 = copy (*_1);
goto -> bb3;
}
bb3: {
StorageDead(_4);
StorageDead(_3);
StorageDead(_2);
return;
}
bb4: {
unreachable;
}
}

View file

@ -25,19 +25,19 @@ enum Enum1 {
// EMIT_MIR clone_as_copy.clone_as_copy.PreCodegen.after.mir
fn clone_as_copy(v: &NestCopy) -> NestCopy {
// CHECK-LABEL: fn clone_as_copy(
// CHECK-NOT: = AllCopy { {{.*}} };
// CHECK-NOT: = NestCopy { {{.*}} };
// CHECK: _0 = copy (*_1);
// CHECK: return;
// CHECK: let [[DEAD_VAR:_.*]]: &AllCopy;
// CHECK: bb0: {
// CHECK-NEXT: DBG: [[DEAD_VAR]] = &((*_1).1: AllCopy)
// CHECK-NEXT: _0 = copy (*_1);
// CHECK-NEXT: return;
v.clone()
}
// FIXME: We can merge into exactly one assignment statement.
// EMIT_MIR clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir
fn enum_clone_as_copy(v: &Enum1) -> Enum1 {
// CHECK-LABEL: fn enum_clone_as_copy(
// CHECK-NOT: = Enum1::
// CHECK: _0 = copy (*_1);
// CHECK: _0 = copy (*_1);
// CHECK: bb0: {
// CHECK-NEXT: _0 = copy (*_1);
// CHECK-NEXT: return;
v.clone()
}

View file

@ -8,10 +8,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _12: ();
let mut _13: &std::alloc::Layout;
let _11: ();
scope 3 {
let _8: std::alloc::Layout;
let _8: std::ptr::alignment::AlignmentEnum;
scope 4 {
scope 12 (inlined Layout::size) {
}
@ -27,19 +26,15 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
scope 18 (inlined <std::alloc::Global as Allocator>::deallocate) {
let mut _9: *mut u8;
let mut _14: &std::alloc::Layout;
scope 19 (inlined Layout::size) {
}
scope 20 (inlined NonNull::<u8>::as_ptr) {
}
scope 21 (inlined std::alloc::dealloc) {
let mut _11: usize;
let mut _15: &std::alloc::Layout;
let mut _16: &std::alloc::Layout;
let mut _10: usize;
scope 22 (inlined Layout::size) {
}
scope 23 (inlined Layout::align) {
let mut _10: std::ptr::alignment::AlignmentEnum;
scope 24 (inlined std::ptr::Alignment::as_usize) {
}
}
@ -68,7 +63,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
bb0: {
StorageLive(_8);
StorageLive(_2);
_2 = copy (((*_1).0: std::ptr::Unique<[T]>).0: std::ptr::NonNull<[T]>);
StorageLive(_4);
@ -80,45 +74,31 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb1: {
_6 = AlignOf(T);
StorageLive(_7);
_7 = copy _6 as std::ptr::Alignment (Transmute);
_8 = Layout { size: copy _5, align: copy _7 };
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
StorageDead(_7);
StorageDead(_6);
StorageDead(_4);
StorageLive(_13);
// DBG: _13 = &_8;
StorageDead(_13);
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
}
bb2: {
StorageLive(_14);
// DBG: _14 = &_8;
StorageDead(_14);
StorageLive(_9);
_9 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_15);
// DBG: _15 = &_8;
StorageDead(_15);
StorageLive(_11);
StorageLive(_16);
// DBG: _16 = &_8;
StorageLive(_10);
_10 = copy (_7.0: std::ptr::alignment::AlignmentEnum);
_11 = discriminant(_10);
StorageDead(_10);
StorageDead(_16);
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
_10 = discriminant(_8);
_11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
goto -> bb4;
}
bb4: {
StorageDead(_2);
StorageDead(_8);
return;
}
}

View file

@ -8,10 +8,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _12: ();
let mut _13: &std::alloc::Layout;
let _11: ();
scope 3 {
let _8: std::alloc::Layout;
let _8: std::ptr::alignment::AlignmentEnum;
scope 4 {
scope 12 (inlined Layout::size) {
}
@ -27,19 +26,15 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
scope 18 (inlined <std::alloc::Global as Allocator>::deallocate) {
let mut _9: *mut u8;
let mut _14: &std::alloc::Layout;
scope 19 (inlined Layout::size) {
}
scope 20 (inlined NonNull::<u8>::as_ptr) {
}
scope 21 (inlined std::alloc::dealloc) {
let mut _11: usize;
let mut _15: &std::alloc::Layout;
let mut _16: &std::alloc::Layout;
let mut _10: usize;
scope 22 (inlined Layout::size) {
}
scope 23 (inlined Layout::align) {
let mut _10: std::ptr::alignment::AlignmentEnum;
scope 24 (inlined std::ptr::Alignment::as_usize) {
}
}
@ -68,7 +63,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
bb0: {
StorageLive(_8);
StorageLive(_2);
_2 = copy (((*_1).0: std::ptr::Unique<[T]>).0: std::ptr::NonNull<[T]>);
StorageLive(_4);
@ -80,45 +74,31 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb1: {
_6 = AlignOf(T);
StorageLive(_7);
_7 = copy _6 as std::ptr::Alignment (Transmute);
_8 = Layout { size: copy _5, align: copy _7 };
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
StorageDead(_7);
StorageDead(_6);
StorageDead(_4);
StorageLive(_13);
// DBG: _13 = &_8;
StorageDead(_13);
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
}
bb2: {
StorageLive(_14);
// DBG: _14 = &_8;
StorageDead(_14);
StorageLive(_9);
_9 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_15);
// DBG: _15 = &_8;
StorageDead(_15);
StorageLive(_11);
StorageLive(_16);
// DBG: _16 = &_8;
StorageLive(_10);
_10 = copy (_7.0: std::ptr::alignment::AlignmentEnum);
_11 = discriminant(_10);
StorageDead(_10);
StorageDead(_16);
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
_10 = discriminant(_8);
_11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
goto -> bb4;
}
bb4: {
StorageDead(_2);
StorageDead(_8);
return;
}
}

View file

@ -8,10 +8,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _12: ();
let mut _13: &std::alloc::Layout;
let _11: ();
scope 3 {
let _8: std::alloc::Layout;
let _8: std::ptr::alignment::AlignmentEnum;
scope 4 {
scope 12 (inlined Layout::size) {
}
@ -27,19 +26,15 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
scope 18 (inlined <std::alloc::Global as Allocator>::deallocate) {
let mut _9: *mut u8;
let mut _14: &std::alloc::Layout;
scope 19 (inlined Layout::size) {
}
scope 20 (inlined NonNull::<u8>::as_ptr) {
}
scope 21 (inlined std::alloc::dealloc) {
let mut _11: usize;
let mut _15: &std::alloc::Layout;
let mut _16: &std::alloc::Layout;
let mut _10: usize;
scope 22 (inlined Layout::size) {
}
scope 23 (inlined Layout::align) {
let mut _10: std::ptr::alignment::AlignmentEnum;
scope 24 (inlined std::ptr::Alignment::as_usize) {
}
}
@ -68,7 +63,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
bb0: {
StorageLive(_8);
StorageLive(_2);
_2 = copy (((*_1).0: std::ptr::Unique<[T]>).0: std::ptr::NonNull<[T]>);
StorageLive(_4);
@ -80,45 +74,31 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb1: {
_6 = AlignOf(T);
StorageLive(_7);
_7 = copy _6 as std::ptr::Alignment (Transmute);
_8 = Layout { size: copy _5, align: copy _7 };
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
StorageDead(_7);
StorageDead(_6);
StorageDead(_4);
StorageLive(_13);
// DBG: _13 = &_8;
StorageDead(_13);
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
}
bb2: {
StorageLive(_14);
// DBG: _14 = &_8;
StorageDead(_14);
StorageLive(_9);
_9 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_15);
// DBG: _15 = &_8;
StorageDead(_15);
StorageLive(_11);
StorageLive(_16);
// DBG: _16 = &_8;
StorageLive(_10);
_10 = copy (_7.0: std::ptr::alignment::AlignmentEnum);
_11 = discriminant(_10);
StorageDead(_10);
StorageDead(_16);
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
_10 = discriminant(_8);
_11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
goto -> bb4;
}
bb4: {
StorageDead(_2);
StorageDead(_8);
return;
}
}

View file

@ -8,10 +8,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _12: ();
let mut _13: &std::alloc::Layout;
let _11: ();
scope 3 {
let _8: std::alloc::Layout;
let _8: std::ptr::alignment::AlignmentEnum;
scope 4 {
scope 12 (inlined Layout::size) {
}
@ -27,19 +26,15 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
scope 18 (inlined <std::alloc::Global as Allocator>::deallocate) {
let mut _9: *mut u8;
let mut _14: &std::alloc::Layout;
scope 19 (inlined Layout::size) {
}
scope 20 (inlined NonNull::<u8>::as_ptr) {
}
scope 21 (inlined std::alloc::dealloc) {
let mut _11: usize;
let mut _15: &std::alloc::Layout;
let mut _16: &std::alloc::Layout;
let mut _10: usize;
scope 22 (inlined Layout::size) {
}
scope 23 (inlined Layout::align) {
let mut _10: std::ptr::alignment::AlignmentEnum;
scope 24 (inlined std::ptr::Alignment::as_usize) {
}
}
@ -68,7 +63,6 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
bb0: {
StorageLive(_8);
StorageLive(_2);
_2 = copy (((*_1).0: std::ptr::Unique<[T]>).0: std::ptr::NonNull<[T]>);
StorageLive(_4);
@ -80,45 +74,31 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb1: {
_6 = AlignOf(T);
StorageLive(_7);
_7 = copy _6 as std::ptr::Alignment (Transmute);
_8 = Layout { size: copy _5, align: copy _7 };
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
StorageDead(_7);
StorageDead(_6);
StorageDead(_4);
StorageLive(_13);
// DBG: _13 = &_8;
StorageDead(_13);
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
}
bb2: {
StorageLive(_14);
// DBG: _14 = &_8;
StorageDead(_14);
StorageLive(_9);
_9 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_15);
// DBG: _15 = &_8;
StorageDead(_15);
StorageLive(_11);
StorageLive(_16);
// DBG: _16 = &_8;
StorageLive(_10);
_10 = copy (_7.0: std::ptr::alignment::AlignmentEnum);
_11 = discriminant(_10);
StorageDead(_10);
StorageDead(_16);
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
_10 = discriminant(_8);
_11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_11);
StorageDead(_10);
StorageDead(_9);
goto -> bb4;
}
bb4: {
StorageDead(_2);
StorageDead(_8);
return;
}
}

View file

@ -11,7 +11,7 @@ pub unsafe fn generic_in_place<T: Copy>(ptr: *mut Box<[T]>) {
// CHECK: [[SIZE:_.+]] = std::intrinsics::size_of_val::<[T]>
// CHECK: [[ALIGN:_.+]] = AlignOf(T);
// CHECK: [[B:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute);
// CHECK: [[C:_.+]] = copy ([[B]].0: std::ptr::alignment::AlignmentEnum);
// CHECK: [[C:_.+]] = move ([[B]].0: std::ptr::alignment::AlignmentEnum);
// CHECK: [[D:_.+]] = discriminant([[C]]);
// CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[D]]) ->
std::ptr::drop_in_place(ptr)

View file

@ -60,9 +60,7 @@ fn int_range(_1: usize, _2: usize) -> () {
StorageLive(_9);
// DBG: _12 = &_3;
StorageLive(_6);
StorageLive(_13);
// DBG: _13 = &(_3.0: usize);
StorageLive(_14);
// DBG: _14 = &(_3.1: usize);
StorageLive(_4);
_4 = copy (_3.0: usize);
@ -75,16 +73,12 @@ fn int_range(_1: usize, _2: usize) -> () {
}
bb2: {
StorageDead(_14);
StorageDead(_13);
StorageDead(_6);
StorageDead(_9);
return;
}
bb3: {
StorageDead(_14);
StorageDead(_13);
_7 = copy (_3.0: usize);
StorageLive(_8);
_8 = AddUnchecked(copy _7, const 1_usize);

View file

@ -171,12 +171,9 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
bb0: {
StorageLive(_22);
StorageLive(_29);
StorageLive(_6);
StorageLive(_7);
StorageLive(_33);
StorageLive(_11);
StorageLive(_35);
StorageLive(_20);
StorageLive(_5);
StorageLive(_4);
@ -184,30 +181,18 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
StorageLive(_2);
_2 = ManuallyDrop::<Vec<impl Sized>> { value: copy _1 };
StorageLive(_3);
StorageLive(_30);
// DBG: _30 = &_2;
// DBG: _29 = &(_2.0: std::vec::Vec<impl Sized>);
StorageDead(_30);
StorageLive(_39);
// DBG: _39 = &((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>);
StorageLive(_40);
// DBG: _40 = &(((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner);
StorageDead(_40);
StorageDead(_39);
_3 = &raw const ((((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global);
StorageDead(_3);
StorageLive(_31);
StorageLive(_32);
// DBG: _32 = &_2;
StorageDead(_32);
// DBG: _31 = &((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>);
StorageLive(_41);
// DBG: _41 = &(((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner);
_4 = copy (((((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
_5 = copy _4 as *const impl Sized (Transmute);
_6 = NonNull::<impl Sized> { pointer: copy _5 };
StorageDead(_41);
StorageDead(_31);
_7 = copy _4 as *mut impl Sized (Transmute);
switchInt(const <impl Sized as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
}
@ -215,10 +200,8 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
bb1: {
StorageLive(_10);
StorageLive(_8);
StorageLive(_36);
// DBG: _36 = &_2;
// DBG: _35 = &(_2.0: std::vec::Vec<impl Sized>);
StorageDead(_36);
_8 = copy ((_2.0: std::vec::Vec<impl Sized>).1: usize);
StorageLive(_9);
_9 = Le(copy _8, const <impl Sized as std::mem::SizedTypeProperties>::MAX_SLICE_LEN);
@ -233,10 +216,8 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
bb2: {
StorageLive(_12);
StorageLive(_34);
// DBG: _34 = &_2;
// DBG: _33 = &(_2.0: std::vec::Vec<impl Sized>);
StorageDead(_34);
_12 = copy ((_2.0: std::vec::Vec<impl Sized>).1: usize);
StorageLive(_13);
_13 = Le(copy _12, const <impl Sized as std::mem::SizedTypeProperties>::MAX_SLICE_LEN);
@ -264,12 +245,8 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
}
bb4: {
StorageLive(_37);
StorageLive(_38);
// DBG: _38 = &_2;
StorageDead(_38);
// DBG: _37 = &((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>);
StorageLive(_42);
// DBG: _42 = &(((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner);
StorageLive(_19);
_19 = SizeOf(impl Sized);
@ -291,20 +268,15 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
bb7: {
StorageDead(_19);
StorageDead(_42);
StorageDead(_37);
_22 = std::vec::IntoIter::<impl Sized> { buf: copy _6, phantom: const ZeroSized: PhantomData<impl Sized>, cap: move _20, alloc: const ManuallyDrop::<std::alloc::Global> {{ value: std::alloc::Global }}, ptr: copy _6, end: copy _11 };
StorageDead(_2);
StorageDead(_17);
StorageDead(_4);
StorageDead(_5);
StorageDead(_20);
StorageDead(_35);
StorageDead(_11);
StorageDead(_33);
StorageDead(_7);
StorageDead(_6);
StorageDead(_29);
StorageLive(_23);
_23 = move _22;
goto -> bb8;

View file

@ -70,9 +70,7 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
// DBG: _15 = &((*_3).2: usize);
// DBG: _16 = &((*_3).3: usize);
StorageLive(_6);
StorageLive(_17);
// DBG: _17 = &_13;
StorageLive(_18);
// DBG: _18 = &_15;
_4 = copy ((*_3).0: usize);
_5 = copy ((*_3).2: usize);
@ -81,18 +79,12 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
}
bb1: {
StorageDead(_18);
StorageDead(_17);
goto -> bb4;
}
bb2: {
StorageDead(_18);
StorageDead(_17);
StorageLive(_9);
StorageLive(_19);
// DBG: _19 = &_16;
StorageLive(_20);
// DBG: _20 = &_14;
StorageLive(_7);
_7 = copy ((*_3).3: usize);
@ -105,34 +97,24 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
}
bb3: {
StorageDead(_20);
StorageDead(_19);
goto -> bb4;
}
bb4: {
StorageLive(_10);
StorageLive(_21);
// DBG: _21 = &_15;
StorageLive(_22);
// DBG: _22 = &_13;
_10 = Le(copy _5, copy _4);
switchInt(move _10) -> [0: bb5, otherwise: bb6];
}
bb5: {
StorageDead(_22);
StorageDead(_21);
_0 = const false;
goto -> bb7;
}
bb6: {
StorageDead(_22);
StorageDead(_21);
StorageLive(_23);
// DBG: _23 = &_14;
StorageLive(_24);
// DBG: _24 = &_16;
StorageLive(_11);
_11 = copy ((*_3).1: usize);
@ -141,8 +123,6 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
_0 = Le(move _11, move _12);
StorageDead(_12);
StorageDead(_11);
StorageDead(_24);
StorageDead(_23);
goto -> bb7;
}
@ -152,8 +132,6 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
}
bb8: {
StorageDead(_20);
StorageDead(_19);
_0 = const true;
goto -> bb9;
}

View file

@ -51,9 +51,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
let mut _16: bool;
let mut _20: usize;
let _22: &T;
let mut _34: &std::ptr::NonNull<T>;
let mut _35: &std::ptr::NonNull<T>;
let mut _36: &std::ptr::NonNull<T>;
scope 29 {
let _12: *const T;
scope 30 {
@ -189,11 +186,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
bb5: {
StorageLive(_16);
StorageLive(_34);
// DBG: _34 = &_11;
StorageLive(_35);
_13 = copy _12 as std::ptr::NonNull<T> (Transmute);
// DBG: _35 = &_13;
StorageLive(_14);
_14 = copy _11 as *mut T (Transmute);
StorageLive(_15);
@ -205,8 +198,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
bb6: {
StorageDead(_35);
StorageDead(_34);
StorageDead(_16);
StorageLive(_18);
StorageLive(_17);
@ -219,8 +210,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
bb7: {
StorageDead(_35);
StorageDead(_34);
StorageDead(_16);
StorageDead(_22);
StorageDead(_13);
@ -266,13 +255,10 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
bb13: {
StorageLive(_36);
// DBG: _36 = &_11;
StorageLive(_21);
_21 = copy _11 as *const T (Transmute);
_22 = &(*_21);
StorageDead(_21);
StorageDead(_36);
_23 = Option::<&T>::Some(copy _22);
StorageDead(_22);
StorageDead(_13);

View file

@ -23,9 +23,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
let mut _15: bool;
let mut _19: usize;
let _21: &T;
let mut _27: &std::ptr::NonNull<T>;
let mut _28: &std::ptr::NonNull<T>;
let mut _29: &std::ptr::NonNull<T>;
scope 17 {
let _11: *const T;
scope 18 {
@ -151,11 +148,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb5: {
StorageLive(_15);
StorageLive(_27);
// DBG: _27 = &_10;
StorageLive(_28);
_12 = copy _11 as std::ptr::NonNull<T> (Transmute);
// DBG: _28 = &_12;
StorageLive(_13);
_13 = copy _10 as *mut T (Transmute);
StorageLive(_14);
@ -167,8 +160,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb6: {
StorageDead(_28);
StorageDead(_27);
StorageDead(_15);
StorageLive(_17);
StorageLive(_16);
@ -181,8 +172,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb7: {
StorageDead(_28);
StorageDead(_27);
StorageDead(_15);
StorageDead(_21);
StorageDead(_12);
@ -224,13 +213,10 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb13: {
StorageLive(_29);
// DBG: _29 = &_10;
StorageLive(_20);
_20 = copy _10 as *const T (Transmute);
_21 = &(*_20);
StorageDead(_20);
StorageDead(_29);
_22 = Option::<&T>::Some(copy _21);
StorageDead(_21);
StorageDead(_12);

View file

@ -23,9 +23,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
let mut _15: bool;
let mut _19: usize;
let _21: &T;
let mut _27: &std::ptr::NonNull<T>;
let mut _28: &std::ptr::NonNull<T>;
let mut _29: &std::ptr::NonNull<T>;
scope 17 {
let _11: *const T;
scope 18 {
@ -151,11 +148,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb5: {
StorageLive(_15);
StorageLive(_27);
// DBG: _27 = &_10;
StorageLive(_28);
_12 = copy _11 as std::ptr::NonNull<T> (Transmute);
// DBG: _28 = &_12;
StorageLive(_13);
_13 = copy _10 as *mut T (Transmute);
StorageLive(_14);
@ -167,8 +160,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb6: {
StorageDead(_28);
StorageDead(_27);
StorageDead(_15);
StorageLive(_17);
StorageLive(_16);
@ -181,8 +172,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb7: {
StorageDead(_28);
StorageDead(_27);
StorageDead(_15);
StorageDead(_21);
StorageDead(_12);
@ -224,13 +213,10 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb13: {
StorageLive(_29);
// DBG: _29 = &_10;
StorageLive(_20);
_20 = copy _10 as *const T (Transmute);
_21 = &(*_20);
StorageDead(_20);
StorageDead(_29);
_22 = Option::<&T>::Some(copy _21);
StorageDead(_21);
StorageDead(_12);

View file

@ -23,8 +23,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
let mut _18: bool;
let mut _19: *const T;
let _32: &T;
let mut _38: &std::ptr::NonNull<T>;
let mut _39: &std::ptr::NonNull<T>;
scope 20 {
let _14: std::ptr::NonNull<T>;
let _20: usize;
@ -48,7 +46,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) {
let _26: std::ptr::NonNull<T>;
let mut _40: &std::ptr::NonNull<T>;
scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) {
let mut _21: *mut *const T;
let mut _22: *mut std::ptr::NonNull<T>;
@ -190,10 +187,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_13 = copy ((_12.0: std::slice::Iter<'_, T>).1: *const T);
_14 = copy _13 as std::ptr::NonNull<T> (Transmute);
StorageDead(_13);
StorageLive(_38);
// DBG: _38 = &((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>);
StorageLive(_39);
// DBG: _39 = &_14;
StorageLive(_16);
StorageLive(_15);
_15 = copy ((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>);
@ -204,8 +197,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_18 = Eq(copy _16, copy _17);
StorageDead(_17);
StorageDead(_16);
StorageDead(_39);
StorageDead(_38);
goto -> bb7;
}
@ -222,7 +213,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb8: {
StorageLive(_26);
StorageLive(_40);
StorageLive(_28);
StorageLive(_22);
StorageLive(_23);
@ -275,12 +265,10 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
StorageDead(_23);
StorageDead(_22);
StorageDead(_28);
// DBG: _40 = &_26;
StorageLive(_31);
_31 = copy _26 as *const T (Transmute);
_32 = &(*_31);
StorageDead(_31);
StorageDead(_40);
StorageDead(_26);
_33 = Option::<&T>::Some(copy _32);
StorageDead(_18);

View file

@ -23,8 +23,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
let mut _18: bool;
let mut _19: *const T;
let _32: &T;
let mut _38: &std::ptr::NonNull<T>;
let mut _39: &std::ptr::NonNull<T>;
scope 20 {
let _14: std::ptr::NonNull<T>;
let _20: usize;
@ -48,7 +46,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) {
let _26: std::ptr::NonNull<T>;
let mut _40: &std::ptr::NonNull<T>;
scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) {
let mut _21: *mut *const T;
let mut _22: *mut std::ptr::NonNull<T>;
@ -190,10 +187,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_13 = copy ((_12.0: std::slice::Iter<'_, T>).1: *const T);
_14 = copy _13 as std::ptr::NonNull<T> (Transmute);
StorageDead(_13);
StorageLive(_38);
// DBG: _38 = &((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>);
StorageLive(_39);
// DBG: _39 = &_14;
StorageLive(_16);
StorageLive(_15);
_15 = copy ((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>);
@ -204,8 +197,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
_18 = Eq(copy _16, copy _17);
StorageDead(_17);
StorageDead(_16);
StorageDead(_39);
StorageDead(_38);
goto -> bb7;
}
@ -222,7 +213,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb8: {
StorageLive(_26);
StorageLive(_40);
StorageLive(_28);
StorageLive(_22);
StorageLive(_23);
@ -275,12 +265,10 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
StorageDead(_23);
StorageDead(_22);
StorageDead(_28);
// DBG: _40 = &_26;
StorageLive(_31);
_31 = copy _26 as *const T (Transmute);
_32 = &(*_31);
StorageDead(_31);
StorageDead(_40);
StorageDead(_26);
_33 = Option::<&T>::Some(copy _32);
StorageDead(_18);

View file

@ -6,8 +6,6 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
scope 1 (inlined <std::slice::Iter<'_, T> as ExactSizeIterator>::is_empty) {
let mut _2: *const T;
let mut _7: *const T;
let mut _9: &std::ptr::NonNull<T>;
let mut _10: &std::ptr::NonNull<T>;
scope 2 {
let _3: std::ptr::NonNull<T>;
let _8: usize;
@ -43,10 +41,6 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_2 = copy ((*_1).1: *const T);
_3 = copy _2 as std::ptr::NonNull<T> (Transmute);
StorageDead(_2);
StorageLive(_9);
// DBG: _9 = &((*_1).0: std::ptr::NonNull<T>);
StorageLive(_10);
// DBG: _10 = &_3;
StorageLive(_5);
StorageLive(_4);
_4 = copy ((*_1).0: std::ptr::NonNull<T>);
@ -57,8 +51,6 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_0 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
StorageDead(_10);
StorageDead(_9);
goto -> bb3;
}

View file

@ -6,8 +6,6 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
scope 1 (inlined <std::slice::Iter<'_, T> as ExactSizeIterator>::is_empty) {
let mut _2: *const T;
let mut _7: *const T;
let mut _9: &std::ptr::NonNull<T>;
let mut _10: &std::ptr::NonNull<T>;
scope 2 {
let _3: std::ptr::NonNull<T>;
let _8: usize;
@ -43,10 +41,6 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_2 = copy ((*_1).1: *const T);
_3 = copy _2 as std::ptr::NonNull<T> (Transmute);
StorageDead(_2);
StorageLive(_9);
// DBG: _9 = &((*_1).0: std::ptr::NonNull<T>);
StorageLive(_10);
// DBG: _10 = &_3;
StorageLive(_5);
StorageLive(_4);
_4 = copy ((*_1).0: std::ptr::NonNull<T>);
@ -57,8 +51,6 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
_0 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
StorageDead(_10);
StorageDead(_9);
goto -> bb3;
}

View file

@ -8,8 +8,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
let mut _7: bool;
let mut _8: *mut T;
let mut _21: &mut T;
let mut _22: &std::ptr::NonNull<T>;
let mut _23: &std::ptr::NonNull<T>;
scope 2 {
let _3: std::ptr::NonNull<T>;
let _9: usize;
@ -33,7 +31,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
}
scope 10 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) {
let mut _15: std::ptr::NonNull<T>;
let mut _24: &mut std::ptr::NonNull<T>;
scope 11 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) {
let mut _10: *mut *mut T;
let mut _11: *mut std::ptr::NonNull<T>;
@ -88,10 +85,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
bb1: {
_2 = copy ((*_1).1: *mut T);
_3 = copy _2 as std::ptr::NonNull<T> (Transmute);
StorageLive(_22);
// DBG: _22 = &((*_1).0: std::ptr::NonNull<T>);
StorageLive(_23);
// DBG: _23 = &_3;
StorageLive(_5);
StorageLive(_4);
_4 = copy ((*_1).0: std::ptr::NonNull<T>);
@ -102,8 +95,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
_7 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
StorageDead(_23);
StorageDead(_22);
goto -> bb3;
}
@ -120,7 +111,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
bb4: {
StorageLive(_15);
StorageLive(_24);
StorageLive(_17);
StorageLive(_11);
StorageLive(_12);
@ -173,12 +163,10 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
StorageDead(_12);
StorageDead(_11);
StorageDead(_17);
// DBG: _24 = &_15;
StorageLive(_20);
_20 = copy _15 as *mut T (Transmute);
_21 = &mut (*_20);
StorageDead(_20);
StorageDead(_24);
StorageDead(_15);
_0 = Option::<&mut T>::Some(copy _21);
goto -> bb11;

View file

@ -8,8 +8,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
let mut _7: bool;
let mut _8: *mut T;
let mut _21: &mut T;
let mut _22: &std::ptr::NonNull<T>;
let mut _23: &std::ptr::NonNull<T>;
scope 2 {
let _3: std::ptr::NonNull<T>;
let _9: usize;
@ -33,7 +31,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
}
scope 10 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) {
let mut _15: std::ptr::NonNull<T>;
let mut _24: &mut std::ptr::NonNull<T>;
scope 11 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) {
let mut _10: *mut *mut T;
let mut _11: *mut std::ptr::NonNull<T>;
@ -88,10 +85,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
bb1: {
_2 = copy ((*_1).1: *mut T);
_3 = copy _2 as std::ptr::NonNull<T> (Transmute);
StorageLive(_22);
// DBG: _22 = &((*_1).0: std::ptr::NonNull<T>);
StorageLive(_23);
// DBG: _23 = &_3;
StorageLive(_5);
StorageLive(_4);
_4 = copy ((*_1).0: std::ptr::NonNull<T>);
@ -102,8 +95,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
_7 = Eq(copy _5, copy _6);
StorageDead(_6);
StorageDead(_5);
StorageDead(_23);
StorageDead(_22);
goto -> bb3;
}
@ -120,7 +111,6 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
bb4: {
StorageLive(_15);
StorageLive(_24);
StorageLive(_17);
StorageLive(_11);
StorageLive(_12);
@ -173,12 +163,10 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut
StorageDead(_12);
StorageDead(_11);
StorageDead(_17);
// DBG: _24 = &_15;
StorageLive(_20);
_20 = copy _15 as *mut T (Transmute);
_21 = &mut (*_20);
StorageDead(_20);
StorageDead(_24);
StorageDead(_15);
_0 = Option::<&mut T>::Some(copy _21);
goto -> bb11;

View file

@ -10,9 +10,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
let mut _10: std::ptr::NonNull<T>;
let mut _12: usize;
let _14: &T;
let mut _15: &std::ptr::NonNull<T>;
let mut _16: &std::ptr::NonNull<T>;
let mut _17: &std::ptr::NonNull<T>;
scope 2 {
let _3: *const T;
scope 3 {
@ -70,11 +67,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
bb1: {
StorageLive(_7);
StorageLive(_15);
// DBG: _15 = &_2;
StorageLive(_16);
_4 = copy _3 as std::ptr::NonNull<T> (Transmute);
// DBG: _16 = &_4;
StorageLive(_5);
_5 = copy _2 as *mut T (Transmute);
StorageLive(_6);
@ -86,8 +79,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
}
bb2: {
StorageDead(_16);
StorageDead(_15);
StorageDead(_7);
StorageLive(_10);
StorageLive(_9);
@ -103,8 +94,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
}
bb3: {
StorageDead(_16);
StorageDead(_15);
_0 = const {transmute(0x0000000000000000): Option<&T>};
StorageDead(_7);
goto -> bb8;
@ -127,13 +116,10 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
}
bb7: {
StorageLive(_17);
// DBG: _17 = &_2;
StorageLive(_13);
_13 = copy _2 as *const T (Transmute);
_14 = &(*_13);
StorageDead(_13);
StorageDead(_17);
_0 = Option::<&T>::Some(copy _14);
goto -> bb8;
}

View file

@ -10,9 +10,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
let mut _10: std::ptr::NonNull<T>;
let mut _12: usize;
let _14: &T;
let mut _15: &std::ptr::NonNull<T>;
let mut _16: &std::ptr::NonNull<T>;
let mut _17: &std::ptr::NonNull<T>;
scope 2 {
let _3: *const T;
scope 3 {
@ -70,11 +67,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
bb1: {
StorageLive(_7);
StorageLive(_15);
// DBG: _15 = &_2;
StorageLive(_16);
_4 = copy _3 as std::ptr::NonNull<T> (Transmute);
// DBG: _16 = &_4;
StorageLive(_5);
_5 = copy _2 as *mut T (Transmute);
StorageLive(_6);
@ -86,8 +79,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
}
bb2: {
StorageDead(_16);
StorageDead(_15);
StorageDead(_7);
StorageLive(_10);
StorageLive(_9);
@ -103,8 +94,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
}
bb3: {
StorageDead(_16);
StorageDead(_15);
_0 = const {transmute(0x0000000000000000): Option<&T>};
StorageDead(_7);
goto -> bb8;
@ -127,13 +116,10 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
}
bb7: {
StorageLive(_17);
// DBG: _17 = &_2;
StorageLive(_13);
_13 = copy _2 as *const T (Transmute);
_14 = &(*_13);
StorageDead(_13);
StorageDead(_17);
_0 = Option::<&T>::Some(copy _14);
goto -> bb8;
}

View file

@ -23,12 +23,17 @@ fn main() {
let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) };
// Projecting to the newtype works, because it is always at offset 0.
let field = &x.0;
// Avoid being eliminated by DSE.
std::hint::black_box(field);
let x: &S = unsafe { &*(&buf as *const _ as *const S) };
// Accessing sized fields is perfectly fine, even at non-zero offsets.
let field = &x.i;
std::hint::black_box(field);
let field = &x.j;
std::hint::black_box(field);
// This needs to compute the field offset, but we don't know the type's alignment,
// so this panics.
let field = &x.a;
std::hint::black_box(field);
}