Auto merge of #81257 - pnkfelix:issue-80949-short-term-resolution-via-revert-of-pr-78373, r=matthewjasper

Revert 78373 ("dont leak return value after panic in drop")

Short term resolution for issue #80949.

Reopen #47949 after this lands.

(We plan to fine-tune PR #78373 to not run into this problem.)
This commit is contained in:
bors 2021-02-05 14:52:57 +00:00 committed by Eric Huss
parent 78e57dc980
commit eba543261d
30 changed files with 10893 additions and 11032 deletions

View file

@ -3,7 +3,6 @@ use crate::build::ForGuard::OutsideGuard;
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use crate::thir::*;
use rustc_hir as hir;
use rustc_middle::middle::region;
use rustc_middle::mir::*;
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
use rustc_session::lint::Level;
@ -13,7 +12,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
crate fn ast_block(
&mut self,
destination: Place<'tcx>,
scope: Option<region::Scope>,
block: BasicBlock,
ast_block: &'tcx hir::Block<'tcx>,
source_info: SourceInfo,
@ -30,10 +28,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
if targeted_by_break {
this.in_breakable_scope(None, destination, scope, span, |this| {
this.in_breakable_scope(None, destination, span, |this| {
Some(this.ast_block_stmts(
destination,
scope,
block,
span,
stmts,
@ -42,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
))
})
} else {
this.ast_block_stmts(destination, scope, block, span, stmts, expr, safety_mode)
this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode)
}
})
})
@ -51,7 +48,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn ast_block_stmts(
&mut self,
destination: Place<'tcx>,
scope: Option<region::Scope>,
mut block: BasicBlock,
span: Span,
stmts: Vec<StmtRef<'tcx>>,
@ -186,7 +182,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });
unpack!(block = this.into(destination, scope, block, expr));
unpack!(block = this.into(destination, block, expr));
let popped = this.block_context.pop();
assert!(popped.map_or(false, |bf| bf.is_tail_expr()));

View file

@ -12,8 +12,6 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, UpvarSubsts};
use rustc_span::Span;
use std::slice;
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Returns an rvalue suitable for use until the end of the current
/// scope expression.
@ -115,19 +113,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
this.cfg.push_assign(block, source_info, Place::from(result), box_);
// Initialize the box contents. No scope is needed since the
// `Box` is already scheduled to be dropped.
// initialize the box contents:
unpack!(
block = this.into(
this.hir.tcx().mk_place_deref(Place::from(result)),
None,
block,
value,
)
block =
this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value)
);
let result_operand = Operand::Move(Place::from(result));
this.record_operands_moved(slice::from_ref(&result_operand));
block.and(Rvalue::Use(result_operand))
block.and(Rvalue::Use(Operand::Move(Place::from(result))))
}
ExprKind::Cast { source } => {
let source = unpack!(block = this.as_operand(block, scope, source));
@ -171,7 +162,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.map(|f| unpack!(block = this.as_operand(block, scope, f)))
.collect();
this.record_operands_moved(&fields);
block.and(Rvalue::Aggregate(box AggregateKind::Array(el_ty), fields))
}
ExprKind::Tuple { fields } => {
@ -182,7 +172,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.map(|f| unpack!(block = this.as_operand(block, scope, f)))
.collect();
this.record_operands_moved(&fields);
block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields))
}
ExprKind::Closure { closure_id, substs, upvars, movability } => {
@ -234,7 +223,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
UpvarSubsts::Closure(substs) => box AggregateKind::Closure(closure_id, substs),
};
this.record_operands_moved(&operands);
block.and(Rvalue::Aggregate(result, operands))
}
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {

View file

@ -114,7 +114,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
unpack!(block = this.into(temp_place, temp_lifetime, block, expr));
unpack!(block = this.into(temp_place, block, expr));
if let Some(temp_lifetime) = temp_lifetime {
this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value);
}
block.and(temp)
}

View file

@ -1,37 +1,27 @@
//! See docs in build/expr/mod.rs
use crate::build::expr::category::{Category, RvalueFunc};
use crate::build::scope::DropKind;
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use crate::thir::*;
use rustc_ast::InlineAsmOptions;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
use rustc_middle::middle::region;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation};
use rustc_span::symbol::sym;
use rustc_target::spec::abi::Abi;
use std::slice;
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Compile `expr`, storing the result into `destination`, which
/// is assumed to be uninitialized.
/// If a `drop_scope` is provided, `destination` is scheduled to be dropped
/// in `scope` once it has been initialized.
crate fn into_expr(
&mut self,
destination: Place<'tcx>,
scope: Option<region::Scope>,
mut block: BasicBlock,
expr: Expr<'tcx>,
) -> BlockAnd<()> {
debug!(
"into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})",
destination, scope, block, expr
);
debug!("into_expr(destination={:?}, block={:?}, expr={:?})", destination, block, expr);
// since we frequently have to reference `self` from within a
// closure, where `self` would be shadowed, it's easier to
@ -46,14 +36,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
_ => false,
};
let schedule_drop = move |this: &mut Self| {
if let Some(drop_scope) = scope {
let local =
destination.as_local().expect("cannot schedule drop of non-Local place");
this.schedule_drop(expr_span, drop_scope, local, DropKind::Value);
}
};
if !expr_is_block_or_scope {
this.block_context.push(BlockFrame::SubExpr);
}
@ -63,15 +45,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let region_scope = (region_scope, source_info);
ensure_sufficient_stack(|| {
this.in_scope(region_scope, lint_level, |this| {
this.into(destination, scope, block, value)
this.into(destination, block, value)
})
})
}
ExprKind::Block { body: ast_block } => {
this.ast_block(destination, scope, block, ast_block, source_info)
this.ast_block(destination, block, ast_block, source_info)
}
ExprKind::Match { scrutinee, arms } => {
this.match_expr(destination, scope, expr_span, block, scrutinee, arms)
this.match_expr(destination, expr_span, block, scrutinee, arms)
}
ExprKind::NeverToAny { source } => {
let source = this.hir.mirror(source);
@ -83,7 +65,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// This is an optimization. If the expression was a call then we already have an
// unreachable block. Don't bother to terminate it and create a new one.
schedule_drop(this);
if is_call {
block.unit()
} else {
@ -159,35 +140,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Start the loop.
this.cfg.goto(block, source_info, loop_block);
this.in_breakable_scope(
Some(loop_block),
destination,
scope,
expr_span,
move |this| {
// conduct the test, if necessary
let body_block = this.cfg.start_new_block();
this.cfg.terminate(
loop_block,
source_info,
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
);
this.diverge_from(loop_block);
this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
// conduct the test, if necessary
let body_block = this.cfg.start_new_block();
this.cfg.terminate(
loop_block,
source_info,
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
);
this.diverge_from(loop_block);
// The “return” value of the loop body must always be an unit. We therefore
// introduce a unit temporary as the destination for the loop body.
let tmp = this.get_unit_temp();
// Execute the body, branching back to the test.
// We don't need to provide a drop scope because `tmp`
// has type `()`.
let body_block_end = unpack!(this.into(tmp, None, body_block, body));
this.cfg.goto(body_block_end, source_info, loop_block);
schedule_drop(this);
// The “return” value of the loop body must always be an unit. We therefore
// introduce a unit temporary as the destination for the loop body.
let tmp = this.get_unit_temp();
// Execute the body, branching back to the test.
let body_block_end = unpack!(this.into(tmp, body_block, body));
this.cfg.goto(body_block_end, source_info, loop_block);
// Loops are only exited by `break` expressions.
None
},
)
// Loops are only exited by `break` expressions.
None
})
}
ExprKind::Call { ty, fun, args, from_hir_call, fn_span } => {
let intrinsic = match *ty.kind() {
@ -220,13 +192,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.push(LocalDecl::with_source_info(ptr_ty, source_info).internal());
let ptr_temp = Place::from(ptr_temp);
// No need for a scope, ptr_temp doesn't need drop
let block = unpack!(this.into(ptr_temp, None, block, ptr));
let block = unpack!(this.into(ptr_temp, block, ptr));
// Maybe we should provide a scope here so that
// `move_val_init` wouldn't leak on panic even with an
// arbitrary `val` expression, but `schedule_drop`,
// borrowck and drop elaboration all prevent us from
// dropping `ptr_temp.deref()`.
this.into(this.hir.tcx().mk_place_deref(ptr_temp), None, block, val)
this.into(this.hir.tcx().mk_place_deref(ptr_temp), block, val)
} else {
let args: Vec<_> = args
.into_iter()
@ -259,11 +231,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
},
);
this.diverge_from(block);
schedule_drop(this);
success.unit()
}
}
ExprKind::Use { source } => this.into(destination, scope, block, source),
ExprKind::Use { source } => this.into(destination, block, source),
ExprKind::Borrow { arg, borrow_kind } => {
// We don't do this in `as_rvalue` because we use `as_place`
// for borrow expressions, so we cannot create an `RValue` that
@ -340,14 +311,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
user_ty,
active_field_index,
);
this.record_operands_moved(&fields);
this.cfg.push_assign(
block,
source_info,
destination,
Rvalue::Aggregate(adt, fields),
);
schedule_drop(this);
block.unit()
}
ExprKind::InlineAsm { template, operands, options, line_spans } => {
@ -444,7 +413,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let place = unpack!(block = this.as_place(block, expr));
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
this.cfg.push_assign(block, source_info, destination, rvalue);
schedule_drop(this);
block.unit()
}
ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => {
@ -462,7 +430,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let place = unpack!(block = this.as_place(block, expr));
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
this.cfg.push_assign(block, source_info, destination, rvalue);
schedule_drop(this);
block.unit()
}
@ -470,14 +437,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let scope = this.local_scope();
let value = unpack!(block = this.as_operand(block, Some(scope), value));
let resume = this.cfg.start_new_block();
this.record_operands_moved(slice::from_ref(&value));
this.cfg.terminate(
block,
source_info,
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
);
this.generator_drop_cleanup(block);
schedule_drop(this);
resume.unit()
}
@ -509,7 +474,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let rvalue = unpack!(block = this.as_local_rvalue(block, expr));
this.cfg.push_assign(block, source_info, destination, rvalue);
schedule_drop(this);
block.unit()
}
};

View file

@ -3,7 +3,6 @@ use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use crate::thir::*;
use rustc_middle::middle::region;
use rustc_middle::mir::*;
use std::slice;
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Builds a block of MIR statements to evaluate the THIR `expr`.
@ -47,7 +46,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if this.hir.needs_drop(lhs.ty) {
let rhs = unpack!(block = this.as_local_operand(block, rhs));
let lhs = unpack!(block = this.as_place(block, lhs));
this.record_operands_moved(slice::from_ref(&rhs));
unpack!(block = this.build_drop_and_replace(block, lhs_span, lhs, rhs));
} else {
let rhs = unpack!(block = this.as_local_rvalue(block, rhs));

View file

@ -6,7 +6,6 @@
use crate::build::{BlockAnd, Builder};
use crate::thir::*;
use rustc_middle::middle::region;
use rustc_middle::mir::*;
pub(in crate::build) trait EvalInto<'tcx> {
@ -14,7 +13,6 @@ pub(in crate::build) trait EvalInto<'tcx> {
self,
builder: &mut Builder<'_, 'tcx>,
destination: Place<'tcx>,
scope: Option<region::Scope>,
block: BasicBlock,
) -> BlockAnd<()>;
}
@ -23,14 +21,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
crate fn into<E>(
&mut self,
destination: Place<'tcx>,
scope: Option<region::Scope>,
block: BasicBlock,
expr: E,
) -> BlockAnd<()>
where
E: EvalInto<'tcx>,
{
expr.eval_into(self, destination, scope, block)
expr.eval_into(self, destination, block)
}
}
@ -39,11 +36,10 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
self,
builder: &mut Builder<'_, 'tcx>,
destination: Place<'tcx>,
scope: Option<region::Scope>,
block: BasicBlock,
) -> BlockAnd<()> {
let expr = builder.hir.mirror(self);
builder.into_expr(destination, scope, block, expr)
builder.into_expr(destination, block, expr)
}
}
@ -52,9 +48,8 @@ impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
self,
builder: &mut Builder<'_, 'tcx>,
destination: Place<'tcx>,
scope: Option<region::Scope>,
block: BasicBlock,
) -> BlockAnd<()> {
builder.into_expr(destination, scope, block, self)
builder.into_expr(destination, block, self)
}
}

View file

@ -87,7 +87,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
crate fn match_expr(
&mut self,
destination: Place<'tcx>,
destination_scope: Option<region::Scope>,
span: Span,
mut block: BasicBlock,
scrutinee: ExprRef<'tcx>,
@ -108,7 +107,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.lower_match_arms(
destination,
destination_scope,
scrutinee_place,
scrutinee_span,
arm_candidates,
@ -215,13 +213,76 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
/// Lower the bindings, guards and arm bodies of a `match` expression.
///
/// The decision tree should have already been created
/// (by [Builder::lower_match_tree]).
///
/// `outer_source_info` is the SourceInfo for the whole match.
fn lower_match_arms(
&mut self,
destination: Place<'tcx>,
scrutinee_place: Place<'tcx>,
scrutinee_span: Span,
arm_candidates: Vec<(&'_ Arm<'tcx>, Candidate<'_, 'tcx>)>,
outer_source_info: SourceInfo,
fake_borrow_temps: Vec<(Place<'tcx>, Local)>,
) -> BlockAnd<()> {
let arm_end_blocks: Vec<_> = arm_candidates
.into_iter()
.map(|(arm, candidate)| {
debug!("lowering arm {:?}\ncandidate = {:?}", arm, candidate);
let arm_source_info = self.source_info(arm.span);
let arm_scope = (arm.scope, arm_source_info);
self.in_scope(arm_scope, arm.lint_level, |this| {
let body = this.hir.mirror(arm.body.clone());
let scope = this.declare_bindings(
None,
arm.span,
&arm.pattern,
ArmHasGuard(arm.guard.is_some()),
Some((Some(&scrutinee_place), scrutinee_span)),
);
let arm_block = this.bind_pattern(
outer_source_info,
candidate,
arm.guard.as_ref(),
&fake_borrow_temps,
scrutinee_span,
Some(arm.span),
Some(arm.scope),
);
if let Some(source_scope) = scope {
this.source_scope = source_scope;
}
this.into(destination, arm_block, body)
})
})
.collect();
// all the arm blocks will rejoin here
let end_block = self.cfg.start_new_block();
for arm_block in arm_end_blocks {
self.cfg.goto(unpack!(arm_block), outer_source_info, end_block);
}
self.source_scope = outer_source_info.scope;
end_block.unit()
}
/// Binds the variables and ascribes types for a given `match` arm or
/// `let` binding.
///
/// Also check if the guard matches, if it's provided.
/// `arm_scope` should be `Some` if and only if this is called for a
/// `match` arm.
crate fn bind_pattern(
fn bind_pattern(
&mut self,
outer_source_info: SourceInfo,
candidate: Candidate<'_, 'tcx>,
@ -308,14 +369,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
let place =
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
let region_scope = self.hir.region_scope_tree.var_scope(var.local_id);
unpack!(block = self.into(place, Some(region_scope), block, initializer));
unpack!(block = self.into(place, block, initializer));
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
let source_info = self.source_info(irrefutable_pat.span);
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForLet, place);
self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
block.unit()
}
@ -342,10 +402,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ascription:
thir::pattern::Ascription { user_ty: pat_ascription_ty, variance: _, user_ty_span },
} => {
let region_scope = self.hir.region_scope_tree.var_scope(var.local_id);
let place =
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
unpack!(block = self.into(place, Some(region_scope), block, initializer));
unpack!(block = self.into(place, block, initializer));
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
let pattern_source_info = self.source_info(irrefutable_pat.span);
@ -383,6 +442,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
},
);
self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
block.unit()
}
@ -629,7 +689,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
#[derive(Debug)]
pub(super) struct Candidate<'pat, 'tcx> {
struct Candidate<'pat, 'tcx> {
/// `Span` of the original pattern that gave rise to this candidate
span: Span,

View file

@ -618,12 +618,8 @@ where
let arg_scope_s = (arg_scope, source_info);
// Attribute epilogue to function's closing brace
let fn_end = span_with_body.shrink_to_hi();
let return_block = unpack!(builder.in_breakable_scope(
None,
Place::return_place(),
Some(call_site_scope),
fn_end,
|builder| {
let return_block =
unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
builder.args_and_body(
START_BLOCK,
@ -633,13 +629,11 @@ where
&body.value,
)
}))
},
));
}));
let source_info = builder.source_info(fn_end);
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
let should_abort = should_abort_on_panic(tcx, fn_def_id, abi);
builder.build_drop_trees(should_abort);
builder.unschedule_return_place_drop();
return_block.unit()
}));
@ -672,9 +666,7 @@ fn construct_const<'a, 'tcx>(
let mut block = START_BLOCK;
let ast_expr = &tcx.hir().body(body_id).value;
let expr = builder.hir.mirror(ast_expr);
// We don't provide a scope because we can't unwind in constants, so won't
// need to drop the return place.
unpack!(block = builder.into_expr(Place::return_place(), None, block, expr));
unpack!(block = builder.into_expr(Place::return_place(), block, expr));
let source_info = builder.source_info(span);
builder.cfg.terminate(block, source_info, TerminatorKind::Return);
@ -963,9 +955,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
let body = self.hir.mirror(ast_body);
let call_site =
region::Scope { id: ast_body.hir_id.local_id, data: region::ScopeData::CallSite };
self.into(Place::return_place(), Some(call_site), block, body)
self.into(Place::return_place(), block, body)
}
fn set_correct_source_scope_for_arg(

View file

@ -81,10 +81,9 @@ that contains only loops and breakable blocks. It tracks where a `break`,
*/
use crate::build::matches::{ArmHasGuard, Candidate};
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG};
use crate::thir::{Arm, Expr, ExprRef, LintLevel};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use crate::thir::{Expr, ExprRef, LintLevel};
use rustc_data_structures::fx::FxHashMap;
use rustc_index::vec::IndexVec;
use rustc_middle::middle::region;
use rustc_middle::mir::*;
@ -121,6 +120,8 @@ struct Scope {
/// end of the vector (top of the stack) first.
drops: Vec<DropData>,
moved_locals: Vec<Local>,
/// The drop index that will drop everything in and below this scope on an
/// unwind path.
cached_unwind_block: Option<DropIdx>,
@ -156,8 +157,6 @@ struct BreakableScope<'tcx> {
/// The destination of the loop/block expression itself (i.e., where to put
/// the result of a `break` or `return` expression)
break_destination: Place<'tcx>,
/// The scope that the destination should have its drop scheduled in.
destination_scope: Option<region::Scope>,
/// Drops that happen on the `break`/`return` path.
break_drops: DropTree,
/// Drops that happen on the `continue` path.
@ -406,6 +405,7 @@ impl<'tcx> Scopes<'tcx> {
region_scope: region_scope.0,
region_scope_span: region_scope.1.span,
drops: vec![],
moved_locals: vec![],
cached_unwind_block: None,
cached_generator_drop_block: None,
});
@ -440,7 +440,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
loop_block: Option<BasicBlock>,
break_destination: Place<'tcx>,
destination_scope: Option<region::Scope>,
span: Span,
f: F,
) -> BlockAnd<()>
@ -451,19 +450,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let scope = BreakableScope {
region_scope,
break_destination,
destination_scope,
break_drops: DropTree::new(),
continue_drops: loop_block.map(|_| DropTree::new()),
};
let continue_block = loop_block.map(|block| (block, self.diverge_cleanup()));
self.scopes.breakable_scopes.push(scope);
let normal_exit_block = f(self);
let breakable_scope = self.scopes.breakable_scopes.pop().unwrap();
assert!(breakable_scope.region_scope == region_scope);
if let Some(drops) = breakable_scope.continue_drops {
self.build_exit_tree(drops, continue_block);
}
let break_block = self.build_exit_tree(breakable_scope.break_drops, None);
if let Some(drops) = breakable_scope.continue_drops {
self.build_exit_tree(drops, loop_block);
}
match (normal_exit_block, break_block) {
(Some(block), None) | (None, Some(block)) => block,
(None, None) => self.cfg.start_new_block().unit(),
@ -592,22 +589,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.rposition(|breakable_scope| breakable_scope.region_scope == scope)
.unwrap_or_else(|| span_bug!(span, "no enclosing breakable scope found"))
};
let (break_index, destination, dest_scope) = match target {
let (break_index, destination) = match target {
BreakableTarget::Return => {
let scope = &self.scopes.breakable_scopes[0];
if scope.break_destination != Place::return_place() {
span_bug!(span, "`return` in item with no return scope");
}
(0, Some(scope.break_destination), scope.destination_scope)
(0, Some(scope.break_destination))
}
BreakableTarget::Break(scope) => {
let break_index = get_scope_index(scope);
let scope = &self.scopes.breakable_scopes[break_index];
(break_index, Some(scope.break_destination), scope.destination_scope)
(break_index, Some(scope.break_destination))
}
BreakableTarget::Continue(scope) => {
let break_index = get_scope_index(scope);
(break_index, None, None)
(break_index, None)
}
};
@ -615,10 +612,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if let Some(value) = value {
debug!("stmt_expr Break val block_context.push(SubExpr)");
self.block_context.push(BlockFrame::SubExpr);
unpack!(block = self.into(destination, dest_scope, block, value));
if let Some(scope) = dest_scope {
self.unschedule_drop(scope, destination.as_local().unwrap())
};
unpack!(block = self.into(destination, block, value));
self.block_context.pop();
} else {
self.cfg.push_assign_unit(block, source_info, destination, self.hir.tcx())
@ -858,47 +852,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
span_bug!(span, "region scope {:?} not in scope to drop {:?}", region_scope, local);
}
/// Unschedule a drop. Used for `break`, `return` and `match` expressions,
/// where `record_operands_moved` is not powerful enough.
///
/// The given local is expected to have a value drop scheduled in the given
/// scope and for that drop to be the most recent thing scheduled in that
/// scope.
fn unschedule_drop(&mut self, region_scope: region::Scope, local: Local) {
if !self.hir.needs_drop(self.local_decls[local].ty) {
return;
}
for scope in self.scopes.scopes.iter_mut().rev() {
scope.invalidate_cache();
if scope.region_scope == region_scope {
let drop = scope.drops.pop();
match drop {
Some(DropData { local: removed_local, kind: DropKind::Value, .. })
if removed_local == local =>
{
return;
}
_ => bug!(
"found wrong drop, expected value drop of {:?}, found {:?}",
local,
drop,
),
}
}
}
bug!("region scope {:?} not in scope to unschedule drop of {:?}", region_scope, local);
}
/// Indicates that the "local operands" stored in `local` is
/// Indicates that the "local operand" stored in `local` is
/// *moved* at some point during execution (see `local_scope` for
/// more information about what a "local operand" is -- in short,
/// it's an intermediate operand created as part of preparing some
/// MIR instruction). We use this information to suppress
/// redundant drops. This results in less MIR, but also avoids spurious
/// borrow check errors (c.f. #64391).
/// redundant drops on the non-unwind paths. This results in less
/// MIR, but also avoids spurious borrow check errors
/// (c.f. #64391).
///
/// Example: when compiling the call to `foo` here:
///
@ -937,19 +898,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
// look for moves of a local variable, like `MOVE(_X)`
let locals_moved = operands
.iter()
.filter_map(|operand| match operand {
Operand::Copy(_) | Operand::Constant(_) => None,
Operand::Move(place) => place.as_local(),
})
.collect::<FxHashSet<_>>();
let locals_moved = operands.iter().flat_map(|operand| match operand {
Operand::Copy(_) | Operand::Constant(_) => None,
Operand::Move(place) => place.as_local(),
});
// Remove the drops for the moved operands.
scope
.drops
.retain(|drop| drop.kind == DropKind::Storage || !locals_moved.contains(&drop.local));
scope.invalidate_cache();
for local in locals_moved {
// check if we have a Drop for this operand and -- if so
// -- add it to the list of moved operands. Note that this
// local might not have been an operand created for this
// call, it could come from other places too.
if scope.drops.iter().any(|drop| drop.local == local && drop.kind == DropKind::Value) {
scope.moved_locals.push(local);
}
}
}
// Other
@ -1136,97 +1098,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
success_block
}
/// Lower the arms and guards of a match.
///
/// The decision tree should have already been created (by
/// [Builder::lower_match_tree]).
///
/// This is this module, and not in `build::matches` because we have to do
/// some careful scope manipulation to have the drop of the destination be
/// scheduled at the end of each arm and then cleared for the next arm.
crate fn lower_match_arms(
&mut self,
destination: Place<'tcx>,
destination_scope: Option<region::Scope>,
scrutinee_place: Place<'tcx>,
scrutinee_span: Span,
arm_candidates: Vec<(&'_ Arm<'tcx>, Candidate<'_, 'tcx>)>,
outer_source_info: SourceInfo,
fake_borrow_temps: Vec<(Place<'tcx>, Local)>,
) -> BlockAnd<()> {
if arm_candidates.is_empty() {
// If there are no arms to schedule drops, then we have to do it
// manually.
if let Some(scope) = destination_scope {
self.schedule_drop(
outer_source_info.span,
scope,
destination.as_local().unwrap(),
DropKind::Value,
);
}
return self.cfg.start_new_block().unit();
}
let mut first_arm = true;
let arm_end_blocks: Vec<_> = arm_candidates
.into_iter()
.map(|(arm, candidate)| {
debug!("lowering arm {:?}\ncandidate = {:?}", arm, candidate);
if first_arm {
first_arm = false;
} else if let Some(scope) = destination_scope {
self.unschedule_drop(scope, destination.as_local().unwrap());
}
let arm_source_info = self.source_info(arm.span);
let arm_scope = (arm.scope, arm_source_info);
self.in_scope(arm_scope, arm.lint_level, |this| {
let body = this.hir.mirror(arm.body.clone());
let scope = this.declare_bindings(
None,
arm.span,
&arm.pattern,
ArmHasGuard(arm.guard.is_some()),
Some((Some(&scrutinee_place), scrutinee_span)),
);
let arm_block = this.bind_pattern(
outer_source_info,
candidate,
arm.guard.as_ref(),
&fake_borrow_temps,
scrutinee_span,
Some(arm.span),
Some(arm.scope),
);
if let Some(source_scope) = scope {
this.source_scope = source_scope;
}
this.into(destination, destination_scope, arm_block, body)
})
})
.collect();
// all the arm blocks will rejoin here
let end_block = self.cfg.start_new_block();
for arm_block in arm_end_blocks {
self.cfg.goto(unpack!(arm_block), outer_source_info, end_block);
}
self.source_scope = outer_source_info.scope;
end_block.unit()
}
/// Unschedules any drops in the top scope.
///
/// This is only needed for `match` arm scopes, because they have one
/// entrance per pattern, but only one exit.
pub(super) fn clear_top_scope(&mut self, region_scope: region::Scope) {
crate fn clear_top_scope(&mut self, region_scope: region::Scope) {
let top_scope = self.scopes.scopes.last_mut().unwrap();
assert_eq!(top_scope.region_scope, region_scope);
@ -1234,18 +1110,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
top_scope.drops.clear();
top_scope.invalidate_cache();
}
/// Unschedules the drop of the return place.
///
/// If the return type of a function requires drop, then we schedule it
/// in the outermost scope so that it's dropped if there's a panic while
/// we drop any local variables. But we don't want to drop it if we
/// return normally.
crate fn unschedule_return_place_drop(&mut self) {
assert_eq!(self.scopes.scopes.len(), 1);
assert!(self.scopes.scopes[0].drops.len() <= 1);
self.scopes.scopes[0].drops.clear();
}
}
/// Builds drops for `pop_scope` and `leave_top_scope`.
@ -1292,6 +1156,14 @@ fn build_scope_drops<'tcx>(
debug_assert_eq!(unwind_drops.drops[unwind_to].0.kind, drop_data.kind);
unwind_to = unwind_drops.drops[unwind_to].1;
// If the operand has been moved, and we are not on an unwind
// path, then don't generate the drop. (We only take this into
// account for non-unwind paths so as not to disturb the
// caching mechanism.)
if scope.moved_locals.iter().any(|&o| o == local) {
continue;
}
unwind_drops.add_entry(block, unwind_to);
let next = cfg.start_new_block();
@ -1321,24 +1193,20 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
/// Build a drop tree for a breakable scope.
///
/// If `continue_block` is `Some`, then the tree is for `continue` inside a
/// loop. Otherwise this is for `break` or `return`. The `DropIdx` is the
/// next drop in the case that the drop tree unwinds. This is needed
/// because the drop of the break destination has already been scheduled
/// but it hasn't been initialized on the `continue` paths.
/// loop. Otherwise this is for `break` or `return`.
fn build_exit_tree(
&mut self,
mut drops: DropTree,
continue_block: Option<(BasicBlock, DropIdx)>,
continue_block: Option<BasicBlock>,
) -> Option<BlockAnd<()>> {
let mut blocks = IndexVec::from_elem(None, &drops.drops);
blocks[ROOT_NODE] = continue_block.map(|(block, _)| block);
blocks[ROOT_NODE] = continue_block;
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
// Link the exit drop tree to unwind drop tree.
if drops.drops.iter().any(|(drop, _)| drop.kind == DropKind::Value) {
let unwind_target = continue_block
.map_or_else(|| self.diverge_cleanup(), |(_, unwind_target)| unwind_target);
let unwind_target = self.diverge_cleanup();
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) {
match drop_data.0.kind {

View file

@ -1772,7 +1772,7 @@ fn test_append_drop_leak() {
catch_unwind(move || left.append(&mut right)).unwrap_err();
assert_eq!(DROPS.load(SeqCst), 5);
assert_eq!(DROPS.load(SeqCst), 4); // Rust issue #47949 ate one little piggy
}
#[test]

View file

@ -41,36 +41,44 @@ fn main() -> () {
StorageLive(_5); // scope 3 at $DIR/basic_assignment.rs:19:9: 19:15
StorageLive(_6); // scope 4 at $DIR/basic_assignment.rs:23:14: 23:20
_6 = move _4; // scope 4 at $DIR/basic_assignment.rs:23:14: 23:20
replace(_5 <- move _6) -> [return: bb1, unwind: bb4]; // scope 4 at $DIR/basic_assignment.rs:23:5: 23:11
replace(_5 <- move _6) -> [return: bb1, unwind: bb5]; // scope 4 at $DIR/basic_assignment.rs:23:5: 23:11
}
bb1: {
StorageDead(_6); // scope 4 at $DIR/basic_assignment.rs:23:19: 23:20
_0 = const (); // scope 0 at $DIR/basic_assignment.rs:10:11: 24:2
drop(_5) -> [return: bb2, unwind: bb5]; // scope 3 at $DIR/basic_assignment.rs:24:1: 24:2
drop(_6) -> [return: bb2, unwind: bb6]; // scope 4 at $DIR/basic_assignment.rs:23:19: 23:20
}
bb2: {
StorageDead(_5); // scope 3 at $DIR/basic_assignment.rs:24:1: 24:2
drop(_4) -> [return: bb3, unwind: bb6]; // scope 2 at $DIR/basic_assignment.rs:24:1: 24:2
StorageDead(_6); // scope 4 at $DIR/basic_assignment.rs:23:19: 23:20
_0 = const (); // scope 0 at $DIR/basic_assignment.rs:10:11: 24:2
drop(_5) -> [return: bb3, unwind: bb7]; // scope 3 at $DIR/basic_assignment.rs:24:1: 24:2
}
bb3: {
StorageDead(_5); // scope 3 at $DIR/basic_assignment.rs:24:1: 24:2
drop(_4) -> [return: bb4, unwind: bb8]; // scope 2 at $DIR/basic_assignment.rs:24:1: 24:2
}
bb4: {
StorageDead(_4); // scope 2 at $DIR/basic_assignment.rs:24:1: 24:2
StorageDead(_2); // scope 1 at $DIR/basic_assignment.rs:24:1: 24:2
StorageDead(_1); // scope 0 at $DIR/basic_assignment.rs:24:1: 24:2
return; // scope 0 at $DIR/basic_assignment.rs:24:2: 24:2
}
bb4 (cleanup): {
drop(_5) -> bb5; // scope 3 at $DIR/basic_assignment.rs:24:1: 24:2
}
bb5 (cleanup): {
drop(_4) -> bb6; // scope 2 at $DIR/basic_assignment.rs:24:1: 24:2
drop(_6) -> bb6; // scope 4 at $DIR/basic_assignment.rs:23:19: 23:20
}
bb6 (cleanup): {
drop(_5) -> bb7; // scope 3 at $DIR/basic_assignment.rs:24:1: 24:2
}
bb7 (cleanup): {
drop(_4) -> bb8; // scope 2 at $DIR/basic_assignment.rs:24:1: 24:2
}
bb8 (cleanup): {
resume; // scope 0 at $DIR/basic_assignment.rs:10:1: 24:2
}
}

View file

@ -14,7 +14,7 @@ fn main() -> () {
StorageLive(_1); // scope 0 at $DIR/box_expr.rs:7:9: 7:10
StorageLive(_2); // scope 0 at $DIR/box_expr.rs:7:13: 7:25
_2 = Box(S); // scope 0 at $DIR/box_expr.rs:7:13: 7:25
(*_2) = S::new() -> [return: bb1, unwind: bb5]; // scope 0 at $DIR/box_expr.rs:7:17: 7:25
(*_2) = S::new() -> [return: bb1, unwind: bb7]; // scope 0 at $DIR/box_expr.rs:7:17: 7:25
// mir::Constant
// + span: $DIR/box_expr.rs:7:17: 7:23
// + literal: Const { ty: fn() -> S {S::new}, val: Value(Scalar(<ZST>)) }
@ -22,37 +22,45 @@ fn main() -> () {
bb1: {
_1 = move _2; // scope 0 at $DIR/box_expr.rs:7:13: 7:25
drop(_2) -> bb2; // scope 0 at $DIR/box_expr.rs:7:24: 7:25
}
bb2: {
StorageDead(_2); // scope 0 at $DIR/box_expr.rs:7:24: 7:25
StorageLive(_3); // scope 1 at $DIR/box_expr.rs:8:5: 8:12
StorageLive(_4); // scope 1 at $DIR/box_expr.rs:8:10: 8:11
_4 = move _1; // scope 1 at $DIR/box_expr.rs:8:10: 8:11
_3 = std::mem::drop::<Box<S>>(move _4) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/box_expr.rs:8:5: 8:12
_3 = std::mem::drop::<Box<S>>(move _4) -> [return: bb3, unwind: bb5]; // scope 1 at $DIR/box_expr.rs:8:5: 8:12
// mir::Constant
// + span: $DIR/box_expr.rs:8:5: 8:9
// + literal: Const { ty: fn(std::boxed::Box<S>) {std::mem::drop::<std::boxed::Box<S>>}, val: Value(Scalar(<ZST>)) }
}
bb2: {
bb3: {
StorageDead(_4); // scope 1 at $DIR/box_expr.rs:8:11: 8:12
StorageDead(_3); // scope 1 at $DIR/box_expr.rs:8:12: 8:13
_0 = const (); // scope 0 at $DIR/box_expr.rs:6:11: 9:2
drop(_1) -> bb3; // scope 0 at $DIR/box_expr.rs:9:1: 9:2
drop(_1) -> bb4; // scope 0 at $DIR/box_expr.rs:9:1: 9:2
}
bb3: {
bb4: {
StorageDead(_1); // scope 0 at $DIR/box_expr.rs:9:1: 9:2
return; // scope 0 at $DIR/box_expr.rs:9:2: 9:2
}
bb4 (cleanup): {
drop(_1) -> bb6; // scope 0 at $DIR/box_expr.rs:9:1: 9:2
}
bb5 (cleanup): {
drop(_2) -> bb6; // scope 0 at $DIR/box_expr.rs:7:24: 7:25
drop(_4) -> bb6; // scope 1 at $DIR/box_expr.rs:8:11: 8:12
}
bb6 (cleanup): {
drop(_1) -> bb8; // scope 0 at $DIR/box_expr.rs:9:1: 9:2
}
bb7 (cleanup): {
drop(_2) -> bb8; // scope 0 at $DIR/box_expr.rs:7:24: 7:25
}
bb8 (cleanup): {
resume; // scope 0 at $DIR/box_expr.rs:6:1: 9:2
}
}

View file

@ -5,19 +5,18 @@
let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:21:12: 21:12
let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _7: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _8: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _9: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22
+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _5: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _6: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _7: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 2 {
+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 3 {
+ debug b => _7; // in scope 3 at $DIR/inline-diverging.rs:22:5: 22:22
+ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:22:5: 22:22
+ }
+ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 7 (inlined sleep) { // at $DIR/inline-diverging.rs:22:5: 22:22
@ -41,12 +40,12 @@
- // mir::Constant
// + span: $DIR/inline-diverging.rs:22:16: 22:21
// + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) }
+ StorageLive(_7); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_8); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ _8 = const (); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_7); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ _7 = const (); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:22:5: 22:22
}

View file

@ -6,18 +6,21 @@ fn main() -> () {
let mut _2: S; // in scope 0 at $DIR/issue-41110.rs:8:13: 8:14
let mut _3: S; // in scope 0 at $DIR/issue-41110.rs:8:21: 8:27
let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:8:21: 8:22
let mut _5: bool; // in scope 0 at $DIR/issue-41110.rs:8:27: 8:28
scope 1 {
debug x => _1; // in scope 1 at $DIR/issue-41110.rs:8:9: 8:10
}
bb0: {
_5 = const false; // scope 0 at $DIR/issue-41110.rs:8:9: 8:10
StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:8:9: 8:10
StorageLive(_2); // scope 0 at $DIR/issue-41110.rs:8:13: 8:14
_5 = const true; // scope 0 at $DIR/issue-41110.rs:8:13: 8:14
_2 = S; // scope 0 at $DIR/issue-41110.rs:8:13: 8:14
StorageLive(_3); // scope 0 at $DIR/issue-41110.rs:8:21: 8:27
StorageLive(_4); // scope 0 at $DIR/issue-41110.rs:8:21: 8:22
_4 = S; // scope 0 at $DIR/issue-41110.rs:8:21: 8:22
_3 = S::id(move _4) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-41110.rs:8:21: 8:27
_3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-41110.rs:8:21: 8:27
// mir::Constant
// + span: $DIR/issue-41110.rs:8:23: 8:25
// + literal: Const { ty: fn(S) -> S {S::id}, val: Value(Scalar(<ZST>)) }
@ -25,7 +28,8 @@ fn main() -> () {
bb1: {
StorageDead(_4); // scope 0 at $DIR/issue-41110.rs:8:26: 8:27
_1 = S::other(move _2, move _3) -> bb2; // scope 0 at $DIR/issue-41110.rs:8:13: 8:28
_5 = const false; // scope 0 at $DIR/issue-41110.rs:8:13: 8:28
_1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue-41110.rs:8:13: 8:28
// mir::Constant
// + span: $DIR/issue-41110.rs:8:15: 8:20
// + literal: Const { ty: fn(S, S) {S::other}, val: Value(Scalar(<ZST>)) }
@ -33,6 +37,7 @@ fn main() -> () {
bb2: {
StorageDead(_3); // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
_5 = const false; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
StorageDead(_2); // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
_0 = const (); // scope 0 at $DIR/issue-41110.rs:7:11: 9:2
StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:9:1: 9:2
@ -40,10 +45,26 @@ fn main() -> () {
}
bb3 (cleanup): {
drop(_2) -> bb4; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
goto -> bb5; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
}
bb4 (cleanup): {
goto -> bb5; // scope 0 at $DIR/issue-41110.rs:8:26: 8:27
}
bb5 (cleanup): {
goto -> bb8; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
}
bb6 (cleanup): {
resume; // scope 0 at $DIR/issue-41110.rs:7:1: 9:2
}
bb7 (cleanup): {
drop(_2) -> bb6; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
}
bb8 (cleanup): {
switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue-41110.rs:8:27: 8:28
}
}

View file

@ -25,7 +25,7 @@ fn test() -> () {
StorageLive(_3); // scope 2 at $DIR/issue-41110.rs:17:5: 17:12
StorageLive(_4); // scope 2 at $DIR/issue-41110.rs:17:10: 17:11
_4 = move _2; // scope 2 at $DIR/issue-41110.rs:17:10: 17:11
_3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb5]; // scope 2 at $DIR/issue-41110.rs:17:5: 17:12
_3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue-41110.rs:17:5: 17:12
// mir::Constant
// + span: $DIR/issue-41110.rs:17:5: 17:9
// + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(Scalar(<ZST>)) }
@ -37,53 +37,65 @@ fn test() -> () {
StorageLive(_5); // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
_6 = const false; // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
_5 = move _1; // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
goto -> bb9; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
goto -> bb12; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
}
bb2: {
StorageDead(_5); // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
_0 = const (); // scope 0 at $DIR/issue-41110.rs:14:15: 19:2
drop(_2) -> [return: bb3, unwind: bb6]; // scope 1 at $DIR/issue-41110.rs:19:1: 19:2
goto -> bb3; // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
}
bb3: {
StorageDead(_2); // scope 1 at $DIR/issue-41110.rs:19:1: 19:2
goto -> bb4; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
StorageDead(_5); // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
_0 = const (); // scope 0 at $DIR/issue-41110.rs:14:15: 19:2
drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue-41110.rs:19:1: 19:2
}
bb4: {
StorageDead(_2); // scope 1 at $DIR/issue-41110.rs:19:1: 19:2
goto -> bb5; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
}
bb5: {
_6 = const false; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
return; // scope 0 at $DIR/issue-41110.rs:19:2: 19:2
}
bb5 (cleanup): {
goto -> bb6; // scope 1 at $DIR/issue-41110.rs:19:1: 19:2
}
bb6 (cleanup): {
goto -> bb11; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
goto -> bb8; // scope 2 at $DIR/issue-41110.rs:18:9: 18:10
}
bb7 (cleanup): {
resume; // scope 0 at $DIR/issue-41110.rs:14:1: 19:2
goto -> bb8; // scope 2 at $DIR/issue-41110.rs:17:11: 17:12
}
bb8 (cleanup): {
_2 = move _5; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
goto -> bb5; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
goto -> bb9; // scope 1 at $DIR/issue-41110.rs:19:1: 19:2
}
bb9: {
bb9 (cleanup): {
goto -> bb14; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
}
bb10 (cleanup): {
resume; // scope 0 at $DIR/issue-41110.rs:14:1: 19:2
}
bb11 (cleanup): {
_2 = move _5; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
goto -> bb6; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
}
bb12: {
_2 = move _5; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
goto -> bb2; // scope 2 at $DIR/issue-41110.rs:18:5: 18:6
}
bb10 (cleanup): {
drop(_1) -> bb7; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
bb13 (cleanup): {
drop(_1) -> bb10; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
}
bb11 (cleanup): {
switchInt(_6) -> [false: bb7, otherwise: bb10]; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
bb14 (cleanup): {
switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue-41110.rs:19:1: 19:2
}
}

View file

@ -26,7 +26,7 @@ fn main() -> () {
_8 = const false; // scope 0 at $DIR/issue-41888.rs:7:9: 7:10
StorageLive(_1); // scope 0 at $DIR/issue-41888.rs:7:9: 7:10
StorageLive(_2); // scope 1 at $DIR/issue-41888.rs:8:8: 8:14
_2 = cond() -> [return: bb1, unwind: bb9]; // scope 1 at $DIR/issue-41888.rs:8:8: 8:14
_2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue-41888.rs:8:8: 8:14
// mir::Constant
// + span: $DIR/issue-41888.rs:8:8: 8:12
// + literal: Const { ty: fn() -> bool {cond}, val: Value(Scalar(<ZST>)) }
@ -38,7 +38,7 @@ fn main() -> () {
bb2: {
_0 = const (); // scope 1 at $DIR/issue-41888.rs:14:6: 14:6
goto -> bb7; // scope 1 at $DIR/issue-41888.rs:8:5: 14:6
goto -> bb8; // scope 1 at $DIR/issue-41888.rs:8:5: 14:6
}
bb3: {
@ -47,34 +47,38 @@ fn main() -> () {
_4 = K; // scope 1 at $DIR/issue-41888.rs:9:18: 9:19
_3 = E::F(move _4); // scope 1 at $DIR/issue-41888.rs:9:13: 9:20
StorageDead(_4); // scope 1 at $DIR/issue-41888.rs:9:19: 9:20
goto -> bb12; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
goto -> bb14; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
}
bb4: {
StorageDead(_3); // scope 1 at $DIR/issue-41888.rs:9:19: 9:20
_5 = discriminant(_1); // scope 1 at $DIR/issue-41888.rs:10:16: 10:24
switchInt(move _5) -> [0_isize: bb6, otherwise: bb5]; // scope 1 at $DIR/issue-41888.rs:10:16: 10:24
goto -> bb5; // scope 1 at $DIR/issue-41888.rs:9:19: 9:20
}
bb5: {
_0 = const (); // scope 1 at $DIR/issue-41888.rs:13:10: 13:10
goto -> bb7; // scope 1 at $DIR/issue-41888.rs:10:9: 13:10
StorageDead(_3); // scope 1 at $DIR/issue-41888.rs:9:19: 9:20
_5 = discriminant(_1); // scope 1 at $DIR/issue-41888.rs:10:16: 10:24
switchInt(move _5) -> [0_isize: bb7, otherwise: bb6]; // scope 1 at $DIR/issue-41888.rs:10:16: 10:24
}
bb6: {
_0 = const (); // scope 1 at $DIR/issue-41888.rs:13:10: 13:10
goto -> bb8; // scope 1 at $DIR/issue-41888.rs:10:9: 13:10
}
bb7: {
StorageLive(_6); // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
_9 = const false; // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
_6 = move ((_1 as F).0: K); // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
_0 = const (); // scope 2 at $DIR/issue-41888.rs:10:29: 13:10
StorageDead(_6); // scope 1 at $DIR/issue-41888.rs:13:9: 13:10
goto -> bb7; // scope 1 at $DIR/issue-41888.rs:10:9: 13:10
}
bb7: {
goto -> bb18; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
goto -> bb8; // scope 1 at $DIR/issue-41888.rs:10:9: 13:10
}
bb8: {
goto -> bb20; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb9: {
_7 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
_8 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
_9 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
@ -83,23 +87,27 @@ fn main() -> () {
return; // scope 0 at $DIR/issue-41888.rs:15:2: 15:2
}
bb9 (cleanup): {
goto -> bb10; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb10 (cleanup): {
resume; // scope 0 at $DIR/issue-41888.rs:6:1: 15:2
goto -> bb11; // scope 1 at $DIR/issue-41888.rs:9:19: 9:20
}
bb11 (cleanup): {
goto -> bb12; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb12 (cleanup): {
resume; // scope 0 at $DIR/issue-41888.rs:6:1: 15:2
}
bb13 (cleanup): {
_7 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
_8 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
_9 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
_1 = move _3; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
goto -> bb9; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
goto -> bb10; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
}
bb12: {
bb14: {
_7 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
_8 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
_9 = const true; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
@ -107,38 +115,38 @@ fn main() -> () {
goto -> bb4; // scope 1 at $DIR/issue-41888.rs:9:9: 9:10
}
bb13: {
_7 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
goto -> bb8; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb14 (cleanup): {
goto -> bb10; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb15: {
drop(_1) -> [return: bb13, unwind: bb10]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
_7 = const false; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
goto -> bb9; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb16 (cleanup): {
drop(_1) -> bb10; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
goto -> bb12; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb17: {
drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb18 (cleanup): {
drop(_1) -> bb12; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb19: {
_10 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
switchInt(move _10) -> [0_isize: bb13, otherwise: bb15]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb18: {
switchInt(_7) -> [false: bb13, otherwise: bb17]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
bb20: {
switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb19 (cleanup): {
bb21 (cleanup): {
_11 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
switchInt(move _11) -> [0_isize: bb14, otherwise: bb16]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
bb20 (cleanup): {
switchInt(_7) -> [false: bb10, otherwise: bb19]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
bb22 (cleanup): {
switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue-41888.rs:15:1: 15:2
}
}

View file

@ -30,7 +30,7 @@ fn test() -> Option<Box<u32>> {
StorageLive(_3); // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
StorageLive(_4); // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
_4 = Option::<u32>::None; // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
_3 = <Option<u32> as Try>::into_result(move _4) -> [return: bb1, unwind: bb10]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
_3 = <Option<u32> as Try>::into_result(move _4) -> [return: bb1, unwind: bb12]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
// mir::Constant
// + span: $DIR/issue-62289.rs:9:15: 9:20
// + literal: Const { ty: fn(std::option::Option<u32>) -> std::result::Result<<std::option::Option<u32> as std::ops::Try>::Ok, <std::option::Option<u32> as std::ops::Try>::Error> {<std::option::Option<u32> as std::ops::Try>::into_result}, val: Value(Scalar(<ZST>)) }
@ -48,11 +48,7 @@ fn test() -> Option<Box<u32>> {
(*_2) = _10; // scope 4 at $DIR/issue-62289.rs:9:15: 9:20
StorageDead(_10); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
_1 = move _2; // scope 0 at $DIR/issue-62289.rs:9:10: 9:21
StorageDead(_2); // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
_0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:9:5: 9:22
StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
StorageDead(_3); // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
goto -> bb8; // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
drop(_2) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
}
bb3: {
@ -65,7 +61,7 @@ fn test() -> Option<Box<u32>> {
StorageLive(_8); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
StorageLive(_9); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_9 = _6; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_8 = <NoneError as From<NoneError>>::from(move _9) -> [return: bb5, unwind: bb10]; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_8 = <NoneError as From<NoneError>>::from(move _9) -> [return: bb5, unwind: bb12]; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
// mir::Constant
// + span: $DIR/issue-62289.rs:9:19: 9:20
// + literal: Const { ty: fn(std::option::NoneError) -> std::option::NoneError {<std::option::NoneError as std::convert::From<std::option::NoneError>>::from}, val: Value(Scalar(<ZST>)) }
@ -73,7 +69,7 @@ fn test() -> Option<Box<u32>> {
bb5: {
StorageDead(_9); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_0 = <Option<Box<u32>> as Try>::from_error(move _8) -> [return: bb6, unwind: bb10]; // scope 2 at $DIR/issue-62289.rs:9:15: 9:20
_0 = <Option<Box<u32>> as Try>::from_error(move _8) -> [return: bb6, unwind: bb12]; // scope 2 at $DIR/issue-62289.rs:9:15: 9:20
// mir::Constant
// + span: $DIR/issue-62289.rs:9:15: 9:20
// + literal: Const { ty: fn(<std::option::Option<std::boxed::Box<u32>> as std::ops::Try>::Error) -> std::option::Option<std::boxed::Box<u32>> {<std::option::Option<std::boxed::Box<u32>> as std::ops::Try>::from_error}, val: Value(Scalar(<ZST>)) }
@ -82,29 +78,41 @@ fn test() -> Option<Box<u32>> {
bb6: {
StorageDead(_8); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
drop(_2) -> [return: bb7, unwind: bb9]; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
drop(_2) -> bb9; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
}
bb7: {
StorageDead(_2); // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
StorageDead(_3); // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
goto -> bb8; // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
_0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:9:5: 9:22
drop(_1) -> bb8; // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
}
bb8: {
StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
StorageDead(_3); // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
goto -> bb10; // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
}
bb9: {
StorageDead(_2); // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
StorageDead(_3); // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
goto -> bb10; // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
}
bb10: {
return; // scope 0 at $DIR/issue-62289.rs:10:2: 10:2
}
bb9 (cleanup): {
drop(_0) -> bb11; // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
}
bb10 (cleanup): {
drop(_2) -> bb11; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
}
bb11 (cleanup): {
drop(_1) -> bb13; // scope 0 at $DIR/issue-62289.rs:9:21: 9:22
}
bb12 (cleanup): {
drop(_2) -> bb13; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
}
bb13 (cleanup): {
resume; // scope 0 at $DIR/issue-62289.rs:8:1: 10:2
}
}

View file

@ -28,7 +28,7 @@ fn main() -> () {
bb1: {
StorageDead(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:9:33: 9:34
_1 = std::mem::drop::<String>(move _2) -> bb2; // scope 0 at $DIR/no-spurious-drop-after-call.rs:9:5: 9:35
_1 = std::mem::drop::<String>(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no-spurious-drop-after-call.rs:9:5: 9:35
// mir::Constant
// + span: $DIR/no-spurious-drop-after-call.rs:9:5: 9:19
// + literal: Const { ty: fn(std::string::String) {std::mem::drop::<std::string::String>}, val: Value(Scalar(<ZST>)) }
@ -41,4 +41,12 @@ fn main() -> () {
_0 = const (); // scope 0 at $DIR/no-spurious-drop-after-call.rs:8:11: 10:2
return; // scope 0 at $DIR/no-spurious-drop-after-call.rs:10:2: 10:2
}
bb3 (cleanup): {
drop(_2) -> bb4; // scope 0 at $DIR/no-spurious-drop-after-call.rs:9:34: 9:35
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/no-spurious-drop-after-call.rs:8:1: 10:2
}
}

View file

@ -22,38 +22,62 @@ fn move_out_by_subslice() -> () {
_3 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
(*_3) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
_2 = move _3; // scope 0 at $DIR/uniform_array_move_out.rs:11:14: 11:19
drop(_3) -> [return: bb1, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
}
bb1: {
StorageDead(_3); // scope 0 at $DIR/uniform_array_move_out.rs:11:18: 11:19
StorageLive(_4); // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
StorageLive(_5); // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
_5 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
(*_5) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
_4 = move _5; // scope 0 at $DIR/uniform_array_move_out.rs:11:21: 11:26
drop(_5) -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
}
bb2: {
StorageDead(_5); // scope 0 at $DIR/uniform_array_move_out.rs:11:25: 11:26
_1 = [move _2, move _4]; // scope 0 at $DIR/uniform_array_move_out.rs:11:13: 11:27
drop(_4) -> [return: bb3, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
}
bb3: {
StorageDead(_4); // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
drop(_2) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
}
bb4: {
StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
FakeRead(ForLet, _1); // scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10
StorageLive(_6); // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
_6 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
_0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:10:27: 13:2
drop(_6) -> [return: bb1, unwind: bb3]; // scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
drop(_6) -> [return: bb5, unwind: bb7]; // scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
}
bb1: {
bb5: {
StorageDead(_6); // scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
drop(_1) -> [return: bb6, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
}
bb2: {
bb6: {
StorageDead(_1); // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
return; // scope 0 at $DIR/uniform_array_move_out.rs:13:2: 13:2
}
bb3 (cleanup): {
drop(_1) -> bb4; // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
bb7 (cleanup): {
drop(_1) -> bb10; // scope 0 at $DIR/uniform_array_move_out.rs:13:1: 13:2
}
bb4 (cleanup): {
bb8 (cleanup): {
drop(_4) -> bb9; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
}
bb9 (cleanup): {
drop(_2) -> bb10; // scope 0 at $DIR/uniform_array_move_out.rs:11:26: 11:27
}
bb10 (cleanup): {
resume; // scope 0 at $DIR/uniform_array_move_out.rs:10:1: 13:2
}
}

View file

@ -22,38 +22,62 @@ fn move_out_from_end() -> () {
_3 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
(*_3) = const 1_i32; // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
_2 = move _3; // scope 0 at $DIR/uniform_array_move_out.rs:5:14: 5:19
drop(_3) -> [return: bb1, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
}
bb1: {
StorageDead(_3); // scope 0 at $DIR/uniform_array_move_out.rs:5:18: 5:19
StorageLive(_4); // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
StorageLive(_5); // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
_5 = Box(i32); // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
(*_5) = const 2_i32; // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
_4 = move _5; // scope 0 at $DIR/uniform_array_move_out.rs:5:21: 5:26
drop(_5) -> [return: bb2, unwind: bb8]; // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
}
bb2: {
StorageDead(_5); // scope 0 at $DIR/uniform_array_move_out.rs:5:25: 5:26
_1 = [move _2, move _4]; // scope 0 at $DIR/uniform_array_move_out.rs:5:13: 5:27
drop(_4) -> [return: bb3, unwind: bb9]; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
}
bb3: {
StorageDead(_4); // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
drop(_2) -> [return: bb4, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
}
bb4: {
StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
FakeRead(ForLet, _1); // scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10
StorageLive(_6); // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
_6 = move _1[1 of 2]; // scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
_0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:4:24: 7:2
drop(_6) -> [return: bb1, unwind: bb3]; // scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
drop(_6) -> [return: bb5, unwind: bb7]; // scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
}
bb1: {
bb5: {
StorageDead(_6); // scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
drop(_1) -> [return: bb6, unwind: bb10]; // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
}
bb2: {
bb6: {
StorageDead(_1); // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
return; // scope 0 at $DIR/uniform_array_move_out.rs:7:2: 7:2
}
bb3 (cleanup): {
drop(_1) -> bb4; // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
bb7 (cleanup): {
drop(_1) -> bb10; // scope 0 at $DIR/uniform_array_move_out.rs:7:1: 7:2
}
bb4 (cleanup): {
bb8 (cleanup): {
drop(_4) -> bb9; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
}
bb9 (cleanup): {
drop(_2) -> bb10; // scope 0 at $DIR/uniform_array_move_out.rs:5:26: 5:27
}
bb10 (cleanup): {
resume; // scope 0 at $DIR/uniform_array_move_out.rs:4:1: 7:2
}
}

View file

@ -19,12 +19,12 @@
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
19| 2|}
------------------
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
------------------
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}

View file

@ -70,166 +70,166 @@ For revisions in Pull Requests (PR):
</head>
<body>
<div class="code" style="counter-reset: line 109"><span class="line"> <span><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"><span class="annotation">@0,1,2,3,4,5⦊</span>pub fn block_on&lt;F: Future&gt;(mut future: F) -&gt; F::Output {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let mut future = unsafe { Pin::new_unchecked(&amp;mut future) };</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"></span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> static VTABLE: RawWakerVTable = RawWakerVTable::new(</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| unimplemented!("clone"),</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| unimplemented!("wake"),</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| unimplemented!("wake_by_ref"),</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| (),</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> );</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &amp;VTABLE)) };</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &amp;mut _1
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb23]
111:35-111:66: @0.Call: _2 = Pin::&lt;&amp;mut F&gt;::new_unchecked(move _3) -&gt; [return: bb1, unwind: bb20]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb23]
119:60-119:77: @1.Call: _6 = null::&lt;()&gt;() -&gt; [return: bb2, unwind: bb20]
119:80-119:86: @2[3]: _9 = const {alloc0: &amp;RawWakerVTable}
119:79-119:86: @2[4]: _8 = &amp;(*_9)
119:79-119:86: @2[5]: _7 = &amp;(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb23]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb23]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -&gt; [return: bb3, unwind: bb20]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -&gt; [return: bb4, unwind: bb20]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &amp;_4
120:47-120:53: @4[8]: _11 = &amp;(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb22]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -&gt; [return: bb5, unwind: bb19]
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let mut context = Context::from_waker(&amp;waker)<span class="annotation">⦉@0,1,2,3,4,5</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"></span></span>
<span class="line"><span class="code" style="--layer: 0"> loop {</span></span>
<span class="line"><span class="code" style="--layer: 0"> if let Poll::Ready(</span><span><span class="code odd" style="--layer: 1" title="123:32-123:35: @12[1]: _20 = move ((_14 as Ready).0: &lt;F as std::future::Future&gt;::Output)"><span class="annotation">@10,12,14,15,16,17⦊</span>val<span class="annotation">⦉@10,12,14,15,16,17</span></span></span><span class="code" style="--layer: 0">) = </span><span><span class="code even" style="--layer: 1" title="123:39-123:45: @7[3]: _16 = &amp;mut _2
123:39-123:54: @7.Call: _15 = Pin::&lt;&amp;mut F&gt;::as_mut(move _16) -&gt; [return: bb8, unwind: bb22]
123:39-123:54: @7.Call: _15 = Pin::&lt;&amp;mut F&gt;::as_mut(move _16) -&gt; [return: bb8, unwind: bb19]
123:60-123:72: @8[3]: _18 = &amp;mut _10
123:60-123:72: @8[4]: _17 = &amp;mut (*_18)
123:39-123:73: @8.Call: _14 = &lt;F as Future&gt;::poll(move _15, move _17) -&gt; [return: bb9, unwind: bb22]
123:39-123:73: @8.Call: _14 = &lt;F as Future&gt;::poll(move _15, move _17) -&gt; [return: bb9, unwind: bb19]
123:39-123:73: @9[2]: FakeRead(ForMatchedPlace, _14)"><span class="annotation">@6,7,8,9⦊</span>future.as_mut().poll(&amp;mut context)<span class="annotation">⦉@6,7,8,9</span></span></span><span class="code" style="--layer: 0"> {</span></span>
<span class="line"><span class="code" style="--layer: 0"> break </span><span><span class="code odd" style="--layer: 1" title="124:23-124:26: @12[2]: _0 = move _20"><span class="annotation">@10,12,14,15,16,17⦊</span>val<span class="annotation">⦉@10,12,14,15,16,17</span></span></span><span class="code" style="--layer: 0">;</span></span>
<span class="line"><span class="code" style="--layer: 0"> }</span><span><span class="code even" style="--layer: 1" title="125:14-125:14: @11[0]: _13 = const ()"><span class="annotation">@11,13⦊</span><span class="annotation">⦉@11,13</span></span></span><span class="code" style="--layer: 0"></span></span>

View file

@ -69,9 +69,9 @@ For revisions in Pull Requests (PR):
</style>
</head>
<body>
<div class="code" style="counter-reset: line 92"><span class="line"><span><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<div class="code" style="counter-reset: line 92"><span class="line"><span><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -82,9 +82,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"><span class="annotation">@0,1,2,3,4,5,6,7,8,9,10,11,12,13⦊</span>fn main() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -95,9 +95,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"> let _ = g(10);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -108,9 +108,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"> let _ = h(9);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -121,9 +121,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"> let mut future = Box::pin(i(8));</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -134,9 +134,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"> j(7);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -147,9 +147,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"> l(6);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -160,9 +160,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"> let _ = m(5);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]
@ -173,9 +173,9 @@ For revisions in Pull Requests (PR):
100:5-100:40: @11.Call: _8 = block_on::&lt;Pin&lt;&amp;mut impl Future&gt;&gt;(move _9) -&gt; [return: bb12, unwind: bb14]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"> executor::block_on(future.as_mut());</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb15]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb15]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb15]
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -&gt; [return: bb1, unwind: bb16]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -&gt; [return: bb3, unwind: bb16]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -&gt; [return: bb5, unwind: bb16]
96:22-96:36: @5.Call: _3 = Box::&lt;impl Future&gt;::pin(move _4) -&gt; [return: bb6, unwind: bb15]
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -&gt; [return: bb7, unwind: bb14]

View file

@ -97,13 +97,13 @@ For revisions in Pull Requests (PR):
103:9-103:29: @4[23]: _18 = (_16.0: &amp;&amp;str)
103:9-103:29: @4[26]: _20 = &amp;(*_18)
103:9-103:29: @4[28]: _21 = &lt;&amp;str as std::fmt::Display&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;str, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
103:9-103:29: @4.Call: _19 = ArgumentV1::new::&lt;&amp;str&gt;(move _20, move _21) -&gt; [return: bb5, unwind: bb10]
103:9-103:29: @4.Call: _19 = ArgumentV1::new::&lt;&amp;str&gt;(move _20, move _21) -&gt; [return: bb5, unwind: bb9]
103:9-103:29: @5[2]: _15 = [move _19]
103:9-103:29: @5[5]: _14 = &amp;_15
103:9-103:29: @5[6]: _13 = &amp;(*_14)
103:9-103:29: @5[7]: _12 = move _13 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -&gt; [return: bb6, unwind: bb10]
103:9-103:29: @6.Call: _6 = format(move _7) -&gt; [return: bb7, unwind: bb10]
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -&gt; [return: bb6, unwind: bb9]
103:9-103:29: @6.Call: _6 = format(move _7) -&gt; [return: bb7, unwind: bb9]
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
103:9-103:29: @7[6]: _0 = move _6
104:6-104:6: @8.Return: return"><span class="annotation">@4,5,6,7,8⦊</span>format!("'{}'", val)</span></span>
@ -117,13 +117,13 @@ For revisions in Pull Requests (PR):
103:9-103:29: @4[23]: _18 = (_16.0: &amp;&amp;str)
103:9-103:29: @4[26]: _20 = &amp;(*_18)
103:9-103:29: @4[28]: _21 = &lt;&amp;str as std::fmt::Display&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;str, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
103:9-103:29: @4.Call: _19 = ArgumentV1::new::&lt;&amp;str&gt;(move _20, move _21) -&gt; [return: bb5, unwind: bb10]
103:9-103:29: @4.Call: _19 = ArgumentV1::new::&lt;&amp;str&gt;(move _20, move _21) -&gt; [return: bb5, unwind: bb9]
103:9-103:29: @5[2]: _15 = [move _19]
103:9-103:29: @5[5]: _14 = &amp;_15
103:9-103:29: @5[6]: _13 = &amp;(*_14)
103:9-103:29: @5[7]: _12 = move _13 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -&gt; [return: bb6, unwind: bb10]
103:9-103:29: @6.Call: _6 = format(move _7) -&gt; [return: bb7, unwind: bb10]
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -&gt; [return: bb6, unwind: bb9]
103:9-103:29: @6.Call: _6 = format(move _7) -&gt; [return: bb7, unwind: bb9]
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
103:9-103:29: @7[6]: _0 = move _6
104:6-104:6: @8.Return: return"> }<span class="annotation">⦉@4,5,6,7,8</span></span></span></span></div>

View file

@ -69,122 +69,122 @@ For revisions in Pull Requests (PR):
</style>
</head>
<body>
<div class="code" style="counter-reset: line 52"><span class="line"><span><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
<div class="code" style="counter-reset: line 52"><span class="line"><span><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"><span class="annotation">@0,1,2,3,4,5,6,7⦊</span>fn use_this_lib_crate() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"><span class="annotation">@0,1,2,3,4,5,6,7,8</span>fn use_this_lib_crate() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"> used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"> used_from_bin_crate_and_lib_crate_generic_function("used from library used_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"> used_with_same_type_from_bin_crate_and_lib_crate_generic_function(</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"> used_with_same_type_from_bin_crate_and_lib_crate_generic_function(</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"> "used from library used_crate.rs",</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"> "used from library used_crate.rs",</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"> );</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"> );</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"> let some_vec = vec![5, 6, 7, 8];</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"> let some_vec = vec![5, 6, 7, 8];</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"> used_only_from_this_lib_crate_generic_function(some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"> used_only_from_this_lib_crate_generic_function(some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return"> used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb10]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb10]
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return"> used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="54:5-54:90: @0.Call: _1 = used_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb1, unwind: bb13]
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from library used_crate.rs&quot;) -&gt; [return: bb2, unwind: bb13]
58:20-58:36: @2[5]: _6 = Box([i32; 4])
58:20-58:36: @2[6]: (*_6) = [const 5_i32, const 6_i32, const 7_i32, const 8_i32]
58:20-58:36: @2[7]: _5 = move _6
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
58:20-58:36: @3.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb4, unwind: bb10]
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
59:52-59:60: @4[4]: _8 = move _3
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb5, unwind: bb8]
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb6, unwind: bb8]
53:25-61:2: @6[1]: _0 = const ()
61:2-61:2: @7.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7</span></span></span></span></div>
58:20-58:36: @4.Call: _3 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _4) -&gt; [return: bb5, unwind: bb12]
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
59:52-59:60: @5[4]: _8 = move _3
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _8) -&gt; [return: bb6, unwind: bb9]
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;used ONLY from library used_crate.rs&quot;) -&gt; [return: bb7, unwind: bb10]
53:25-61:2: @7[1]: _0 = const ()
61:2-61:2: @8.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7,8</span></span></span></span></div>
</body>
</html>

View file

@ -69,125 +69,125 @@ For revisions in Pull Requests (PR):
</style>
</head>
<body>
<div class="code" style="counter-reset: line 4"><span class="line"><span><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
<div class="code" style="counter-reset: line 4"><span class="line"><span><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return"><span class="annotation">@0,1,2,3,4,5,6,7,8⦊</span>fn main() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return"><span class="annotation">@0,1,2,3,4,5,6,7,8,9</span>fn main() {</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return"> used_crate::used_function();</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return"> used_crate::used_function();</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return"> let some_vec = vec![1, 2, 3, 4];</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return"> let some_vec = vec![1, 2, 3, 4];</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return"> used_crate::used_only_from_bin_crate_generic_function(&amp;some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return"> used_crate::used_only_from_bin_crate_generic_function(&amp;some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return"> used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return"> used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return"> used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return"> used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return"> used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb11]
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return"> used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");</span></span>
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -&gt; [return: bb1, unwind: bb14]
7:20-7:36: @1[5]: _5 = Box([i32; 4])
7:20-7:36: @1[6]: (*_5) = [const 1_i32, const 2_i32, const 3_i32, const 4_i32]
7:20-7:36: @1[7]: _4 = move _5
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box&lt;[i32]&gt; (Pointer(Unsize))
7:20-7:36: @2.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb3, unwind: bb11]
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
8:59-8:68: @3[4]: _7 = &amp;_2
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb4, unwind: bb9]
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb5, unwind: bb9]
10:68-10:76: @5[3]: _10 = move _2
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb6, unwind: bb9]
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb7, unwind: bb9]
5:11-12:2: @7[1]: _0 = const ()
12:2-12:2: @8.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7,8</span></span></span></span></div>
7:20-7:36: @3.Call: _2 = slice::&lt;impl [i32]&gt;::into_vec::&lt;std::alloc::Global&gt;(move _3) -&gt; [return: bb4, unwind: bb13]
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
8:59-8:68: @4[4]: _7 = &amp;_2
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::&lt;&amp;Vec&lt;i32&gt;&gt;(move _7) -&gt; [return: bb5, unwind: bb11]
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::&lt;&amp;str&gt;(const &quot;used from bin uses_crate.rs&quot;) -&gt; [return: bb6, unwind: bb11]
10:68-10:76: @6[3]: _10 = move _2
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::&lt;Vec&lt;i32&gt;&gt;(move _10) -&gt; [return: bb7, unwind: bb10]
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::&lt;&amp;str&gt;(const &quot;interesting?&quot;) -&gt; [return: bb8, unwind: bb11]
5:11-12:2: @8[1]: _0 = const ()
12:2-12:2: @9.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7,8,9</span></span></span></span></div>
</body>
</html>

View file

@ -43,7 +43,6 @@ impl<T: Unpin> Future for Defer<T> {
/// The `failing_op`-th operation will panic.
struct Allocator {
data: RefCell<Vec<bool>>,
name: &'static str,
failing_op: usize,
cur_ops: Cell<usize>,
}
@ -55,28 +54,23 @@ impl Drop for Allocator {
fn drop(&mut self) {
let data = self.data.borrow();
if data.iter().any(|d| *d) {
panic!("missing free in {:?}: {:?}", self.name, data);
panic!("missing free: {:?}", data);
}
}
}
impl Allocator {
fn new(failing_op: usize, name: &'static str) -> Self {
Allocator {
failing_op,
name,
cur_ops: Cell::new(0),
data: RefCell::new(vec![]),
}
fn new(failing_op: usize) -> Self {
Allocator { failing_op, cur_ops: Cell::new(0), data: RefCell::new(vec![]) }
}
fn alloc(self: &Rc<Allocator>) -> impl Future<Output = Ptr> + 'static {
fn alloc(&self) -> impl Future<Output = Ptr<'_>> + '_ {
self.fallible_operation();
let mut data = self.data.borrow_mut();
let addr = data.len();
data.push(true);
Defer { ready: false, value: Some(Ptr(addr, self.clone())) }
Defer { ready: false, value: Some(Ptr(addr, self)) }
}
fn fallible_operation(&self) {
self.cur_ops.set(self.cur_ops.get() + 1);
@ -89,11 +83,11 @@ impl Allocator {
// Type that tracks whether it was dropped and can panic when it's created or
// destroyed.
struct Ptr(usize, Rc<Allocator>);
impl Drop for Ptr {
struct Ptr<'a>(usize, &'a Allocator);
impl<'a> Drop for Ptr<'a> {
fn drop(&mut self) {
match self.1.data.borrow_mut()[self.0] {
false => panic!("double free in {:?} at index {:?}", self.1.name, self.0),
false => panic!("double free at index {:?}", self.0),
ref mut d => *d = false,
}
@ -117,7 +111,7 @@ async fn dynamic_drop(a: Rc<Allocator>, c: bool) {
};
}
struct TwoPtrs(Ptr, Ptr);
struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>);
async fn struct_dynamic_drop(a: Rc<Allocator>, c0: bool, c1: bool, c: bool) {
for i in 0..2 {
let x;
@ -238,62 +232,21 @@ async fn move_ref_pattern(a: Rc<Allocator>) {
a.alloc().await;
}
async fn panic_after_return(a: Rc<Allocator>, c: bool) -> (Ptr,) {
a.alloc().await;
let p = a.alloc().await;
if c {
a.alloc().await;
let q = a.alloc().await;
// We use a return type that isn't used anywhere else to make sure that
// the return place doesn't incorrectly end up in the generator state.
return (a.alloc().await,);
}
(a.alloc().await,)
}
async fn panic_after_init_by_loop(a: Rc<Allocator>) {
a.alloc().await;
let p = a.alloc().await;
let q = loop {
a.alloc().await;
let r = a.alloc().await;
break a.alloc().await;
};
}
async fn panic_after_init_by_match_with_bindings_and_guard(a: Rc<Allocator>, b: bool) {
a.alloc().await;
let p = a.alloc().await;
let q = match a.alloc().await {
ref _x if b => {
a.alloc().await;
let r = a.alloc().await;
a.alloc().await
}
_x => {
a.alloc().await;
let r = a.alloc().await;
a.alloc().await
},
};
}
fn run_test<F, G, O>(cx: &mut Context<'_>, ref f: F, name: &'static str)
fn run_test<F, G>(cx: &mut Context<'_>, ref f: F)
where
F: Fn(Rc<Allocator>) -> G,
G: Future<Output = O>,
G: Future<Output = ()>,
{
for polls in 0.. {
// Run without any panics to find which operations happen after the
// penultimate `poll`.
let first_alloc = Rc::new(Allocator::new(usize::MAX, name));
let first_alloc = Rc::new(Allocator::new(usize::MAX));
let mut fut = Box::pin(f(first_alloc.clone()));
let mut ops_before_last_poll = 0;
let mut completed = false;
for _ in 0..polls {
ops_before_last_poll = first_alloc.cur_ops.get();
if let Poll::Ready(_) = fut.as_mut().poll(cx) {
if let Poll::Ready(()) = fut.as_mut().poll(cx) {
completed = true;
}
}
@ -302,7 +255,7 @@ where
// Start at `ops_before_last_poll` so that we will always be able to
// `poll` the expected number of times.
for failing_op in ops_before_last_poll..first_alloc.cur_ops.get() {
let alloc = Rc::new(Allocator::new(failing_op + 1, name));
let alloc = Rc::new(Allocator::new(failing_op + 1));
let f = &f;
let cx = &mut *cx;
let result = panic::catch_unwind(panic::AssertUnwindSafe(move || {
@ -332,58 +285,48 @@ fn clone_waker(data: *const ()) -> RawWaker {
RawWaker::new(data, &RawWakerVTable::new(clone_waker, drop, drop, drop))
}
macro_rules! run_test {
($ctxt:expr, $e:expr) => { run_test($ctxt, $e, stringify!($e)); };
}
fn main() {
let waker = unsafe { Waker::from_raw(clone_waker(ptr::null())) };
let context = &mut Context::from_waker(&waker);
run_test!(context, |a| dynamic_init(a, false));
run_test!(context, |a| dynamic_init(a, true));
run_test!(context, |a| dynamic_drop(a, false));
run_test!(context, |a| dynamic_drop(a, true));
run_test(context, |a| dynamic_init(a, false));
run_test(context, |a| dynamic_init(a, true));
run_test(context, |a| dynamic_drop(a, false));
run_test(context, |a| dynamic_drop(a, true));
run_test!(context, |a| assignment(a, false, false));
run_test!(context, |a| assignment(a, false, true));
run_test!(context, |a| assignment(a, true, false));
run_test!(context, |a| assignment(a, true, true));
run_test(context, |a| assignment(a, false, false));
run_test(context, |a| assignment(a, false, true));
run_test(context, |a| assignment(a, true, false));
run_test(context, |a| assignment(a, true, true));
run_test!(context, |a| array_simple(a));
run_test!(context, |a| vec_simple(a));
run_test!(context, |a| vec_unreachable(a));
run_test(context, |a| array_simple(a));
run_test(context, |a| vec_simple(a));
run_test(context, |a| vec_unreachable(a));
run_test!(context, |a| struct_dynamic_drop(a, false, false, false));
run_test!(context, |a| struct_dynamic_drop(a, false, false, true));
run_test!(context, |a| struct_dynamic_drop(a, false, true, false));
run_test!(context, |a| struct_dynamic_drop(a, false, true, true));
run_test!(context, |a| struct_dynamic_drop(a, true, false, false));
run_test!(context, |a| struct_dynamic_drop(a, true, false, true));
run_test!(context, |a| struct_dynamic_drop(a, true, true, false));
run_test!(context, |a| struct_dynamic_drop(a, true, true, true));
run_test(context, |a| struct_dynamic_drop(a, false, false, false));
run_test(context, |a| struct_dynamic_drop(a, false, false, true));
run_test(context, |a| struct_dynamic_drop(a, false, true, false));
run_test(context, |a| struct_dynamic_drop(a, false, true, true));
run_test(context, |a| struct_dynamic_drop(a, true, false, false));
run_test(context, |a| struct_dynamic_drop(a, true, false, true));
run_test(context, |a| struct_dynamic_drop(a, true, true, false));
run_test(context, |a| struct_dynamic_drop(a, true, true, true));
run_test!(context, |a| field_assignment(a, false));
run_test!(context, |a| field_assignment(a, true));
run_test(context, |a| field_assignment(a, false));
run_test(context, |a| field_assignment(a, true));
run_test!(context, |a| mixed_drop_and_nondrop(a));
run_test(context, |a| mixed_drop_and_nondrop(a));
run_test!(context, |a| slice_pattern_one_of(a, 0));
run_test!(context, |a| slice_pattern_one_of(a, 1));
run_test!(context, |a| slice_pattern_one_of(a, 2));
run_test!(context, |a| slice_pattern_one_of(a, 3));
run_test(context, |a| slice_pattern_one_of(a, 0));
run_test(context, |a| slice_pattern_one_of(a, 1));
run_test(context, |a| slice_pattern_one_of(a, 2));
run_test(context, |a| slice_pattern_one_of(a, 3));
run_test!(context, |a| subslice_pattern_from_end_with_drop(a, true, true));
run_test!(context, |a| subslice_pattern_from_end_with_drop(a, true, false));
run_test!(context, |a| subslice_pattern_from_end_with_drop(a, false, true));
run_test!(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
run_test!(context, |a| subslice_pattern_reassign(a));
run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, true));
run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, false));
run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true));
run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
run_test(context, |a| subslice_pattern_reassign(a));
run_test!(context, |a| move_ref_pattern(a));
run_test!(context, |a| panic_after_return(a, false));
run_test!(context, |a| panic_after_return(a, true));
run_test!(context, |a| panic_after_init_by_loop(a));
run_test!(context, |a| panic_after_init_by_match_with_bindings_and_guard(a, false));
run_test!(context, |a| panic_after_init_by_match_with_bindings_and_guard(a, true));
run_test(context, |a| move_ref_pattern(a));
}

View file

@ -3,6 +3,7 @@
#![feature(generators, generator_trait)]
#![feature(bindings_after_at)]
#![allow(unused_assignments)]
#![allow(unused_variables)]
@ -16,7 +17,6 @@ struct InjectedFailure;
struct Allocator {
data: RefCell<Vec<bool>>,
name: &'static str,
failing_op: usize,
cur_ops: Cell<usize>,
}
@ -28,18 +28,17 @@ impl Drop for Allocator {
fn drop(&mut self) {
let data = self.data.borrow();
if data.iter().any(|d| *d) {
panic!("missing free in {:?}: {:?}", self.name, data);
panic!("missing free: {:?}", data);
}
}
}
impl Allocator {
fn new(failing_op: usize, name: &'static str) -> Self {
fn new(failing_op: usize) -> Self {
Allocator {
failing_op: failing_op,
cur_ops: Cell::new(0),
data: RefCell::new(vec![]),
name,
data: RefCell::new(vec![])
}
}
fn alloc(&self) -> Ptr<'_> {
@ -54,17 +53,33 @@ impl Allocator {
data.push(true);
Ptr(addr, self)
}
// FIXME(#47949) Any use of this indicates a bug in rustc: we should never
// be leaking values in the cases here.
//
// Creates a `Ptr<'_>` and checks that the allocated value is leaked if the
// `failing_op` is in the list of exception.
fn alloc_leaked(&self, exceptions: Vec<usize>) -> Ptr<'_> {
let ptr = self.alloc();
if exceptions.iter().any(|operation| *operation == self.failing_op) {
let mut data = self.data.borrow_mut();
data[ptr.0] = false;
}
ptr
}
}
struct Ptr<'a>(usize, &'a Allocator);
impl<'a> Drop for Ptr<'a> {
fn drop(&mut self) {
match self.1.data.borrow_mut()[self.0] {
false => panic!("double free in {:?} at index {:?}", self.1.name, self.0),
ref mut d => *d = false,
false => {
panic!("double free at index {:?}", self.0)
}
ref mut d => *d = false
}
self.1.cur_ops.set(self.1.cur_ops.get() + 1);
self.1.cur_ops.set(self.1.cur_ops.get()+1);
if self.1.cur_ops.get() == self.1.failing_op {
panic!(InjectedFailure);
@ -162,7 +177,11 @@ fn generator(a: &Allocator, run_count: usize) {
assert!(run_count < 4);
let mut gen = || {
(a.alloc(), yield a.alloc(), a.alloc(), yield a.alloc());
(a.alloc(),
yield a.alloc(),
a.alloc(),
yield a.alloc()
);
};
for _ in 0..run_count {
Pin::new(&mut gen).resume(());
@ -186,40 +205,28 @@ fn vec_unreachable(a: &Allocator) {
}
fn slice_pattern_first(a: &Allocator) {
let [_x, ..] = [a.alloc(), a.alloc(), a.alloc()];
let[_x, ..] = [a.alloc(), a.alloc(), a.alloc()];
}
fn slice_pattern_middle(a: &Allocator) {
let [_, _x, _] = [a.alloc(), a.alloc(), a.alloc()];
let[_, _x, _] = [a.alloc(), a.alloc(), a.alloc()];
}
fn slice_pattern_two(a: &Allocator) {
let [_x, _, _y, _] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
let[_x, _, _y, _] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
}
fn slice_pattern_last(a: &Allocator) {
let [.., _y] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
let[.., _y] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
}
fn slice_pattern_one_of(a: &Allocator, i: usize) {
let array = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
let _x = match i {
0 => {
let [a, ..] = array;
a
}
1 => {
let [_, a, ..] = array;
a
}
2 => {
let [_, _, a, _] = array;
a
}
3 => {
let [_, _, _, a] = array;
a
}
0 => { let [a, ..] = array; a }
1 => { let [_, a, ..] = array; a }
2 => { let [_, _, a, _] = array; a }
3 => { let [_, _, _, a] = array; a }
_ => panic!("unmatched"),
};
}
@ -227,9 +234,9 @@ fn slice_pattern_one_of(a: &Allocator, i: usize) {
fn subslice_pattern_from_end(a: &Allocator, arg: bool) {
let a = [a.alloc(), a.alloc(), a.alloc()];
if arg {
let [.., _x, _] = a;
let[.., _x, _] = a;
} else {
let [_, _y @ ..] = a;
let[_, _y @ ..] = a;
}
}
@ -241,61 +248,45 @@ fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) {
}
if arg {
let [.., _x, _] = a;
let[.., _x, _] = a;
} else {
let [_, _y @ ..] = a;
let[_, _y @ ..] = a;
}
}
fn slice_pattern_reassign(a: &Allocator) {
let mut ar = [a.alloc(), a.alloc()];
let [_, _x] = ar;
let[_, _x] = ar;
ar = [a.alloc(), a.alloc()];
let [.., _y] = ar;
let[.., _y] = ar;
}
fn subslice_pattern_reassign(a: &Allocator) {
let mut ar = [a.alloc(), a.alloc(), a.alloc()];
let [_, _, _x] = ar;
let[_, _, _x] = ar;
ar = [a.alloc(), a.alloc(), a.alloc()];
let [_, _y @ ..] = ar;
let[_, _y @ ..] = ar;
}
fn index_field_mixed_ends(a: &Allocator) {
let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
let [(_x, _), ..] = ar;
let [(_, _y), _] = ar;
let [_, (_, _w)] = ar;
let [.., (_z, _)] = ar;
let[(_x, _), ..] = ar;
let[(_, _y), _] = ar;
let[_, (_, _w)] = ar;
let[.., (_z, _)] = ar;
}
fn subslice_mixed_min_lengths(a: &Allocator, c: i32) {
let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
match c {
0 => {
let [_x, ..] = ar;
}
1 => {
let [_x, _, ..] = ar;
}
2 => {
let [_x, _] = ar;
}
3 => {
let [(_x, _), _, ..] = ar;
}
4 => {
let [.., (_x, _)] = ar;
}
5 => {
let [.., (_x, _), _] = ar;
}
6 => {
let [_y @ ..] = ar;
}
_ => {
let [_y @ .., _] = ar;
}
0 => { let[_x, ..] = ar; }
1 => { let[_x, _, ..] = ar; }
2 => { let[_x, _] = ar; }
3 => { let[(_x, _), _, ..] = ar; }
4 => { let[.., (_x, _)] = ar; }
5 => { let[.., (_x, _), _] = ar; }
6 => { let [_y @ ..] = ar; }
_ => { let [_y @ .., _] = ar; }
}
}
@ -343,160 +334,87 @@ fn move_ref_pattern(a: &Allocator) {
}
fn panic_after_return(a: &Allocator) -> Ptr<'_> {
// Panic in the drop of `p` or `q` can leak
let exceptions = vec![8, 9];
a.alloc();
let p = a.alloc();
{
a.alloc();
let p = a.alloc();
a.alloc()
// FIXME (#47949) We leak values when we panic in a destructor after
// evaluating an expression with `rustc_mir::build::Builder::into`.
a.alloc_leaked(exceptions)
}
}
fn panic_after_return_expr(a: &Allocator) -> Ptr<'_> {
// Panic in the drop of `p` or `q` can leak
let exceptions = vec![8, 9];
a.alloc();
let p = a.alloc();
{
a.alloc();
let q = a.alloc();
return a.alloc();
// FIXME (#47949)
return a.alloc_leaked(exceptions);
}
}
fn panic_after_init(a: &Allocator) {
// Panic in the drop of `r` can leak
let exceptions = vec![8];
a.alloc();
let p = a.alloc();
let q = {
a.alloc();
let r = a.alloc();
a.alloc()
// FIXME (#47949)
a.alloc_leaked(exceptions)
};
}
fn panic_after_init_temp(a: &Allocator) {
// Panic in the drop of `r` can leak
let exceptions = vec![8];
a.alloc();
let p = a.alloc();
{
a.alloc();
let r = a.alloc();
a.alloc()
// FIXME (#47949)
a.alloc_leaked(exceptions)
};
}
fn panic_after_init_by_loop(a: &Allocator) {
// Panic in the drop of `r` can leak
let exceptions = vec![8];
a.alloc();
let p = a.alloc();
let q = loop {
a.alloc();
let r = a.alloc();
break a.alloc();
// FIXME (#47949)
break a.alloc_leaked(exceptions);
};
}
fn panic_after_init_by_match(a: &Allocator, b: bool) {
a.alloc();
let p = a.alloc();
let _ = loop {
let q = match b {
true => {
a.alloc();
let r = a.alloc();
a.alloc()
}
false => {
a.alloc();
let r = a.alloc();
break a.alloc();
}
};
return;
};
}
fn panic_after_init_by_match_with_guard(a: &Allocator, b: bool) {
a.alloc();
let p = a.alloc();
let q = match a.alloc() {
_ if b => {
a.alloc();
let r = a.alloc();
a.alloc()
}
_ => {
a.alloc();
let r = a.alloc();
a.alloc()
}
};
}
fn panic_after_init_by_match_with_bindings_and_guard(a: &Allocator, b: bool) {
a.alloc();
let p = a.alloc();
let q = match a.alloc() {
_x if b => {
a.alloc();
let r = a.alloc();
a.alloc()
}
_x => {
a.alloc();
let r = a.alloc();
a.alloc()
}
};
}
fn panic_after_init_by_match_with_ref_bindings_and_guard(a: &Allocator, b: bool) {
a.alloc();
let p = a.alloc();
let q = match a.alloc() {
ref _x if b => {
a.alloc();
let r = a.alloc();
a.alloc()
}
ref _x => {
a.alloc();
let r = a.alloc();
a.alloc()
}
};
}
fn panic_after_init_by_break_if(a: &Allocator, b: bool) {
a.alloc();
let p = a.alloc();
let q = loop {
let r = a.alloc();
break if b {
let s = a.alloc();
a.alloc()
} else {
a.alloc()
};
};
}
fn run_test<F>(mut f: F, name: &'static str)
where
F: FnMut(&Allocator),
fn run_test<F>(mut f: F)
where F: FnMut(&Allocator)
{
let first_alloc = Allocator::new(usize::MAX, name);
let first_alloc = Allocator::new(usize::MAX);
f(&first_alloc);
for failing_op in 1..first_alloc.cur_ops.get() + 1 {
let alloc = Allocator::new(failing_op, name);
for failing_op in 1..first_alloc.cur_ops.get()+1 {
let alloc = Allocator::new(failing_op);
let alloc = &alloc;
let f = panic::AssertUnwindSafe(&mut f);
let result = panic::catch_unwind(move || {
f.0(alloc);
});
match result {
Ok(..) => panic!(
"test executed {} ops but now {}",
first_alloc.cur_ops.get(),
alloc.cur_ops.get()
),
Ok(..) => panic!("test executed {} ops but now {}",
first_alloc.cur_ops.get(), alloc.cur_ops.get()),
Err(e) => {
if e.downcast_ref::<InjectedFailure>().is_none() {
panic::resume_unwind(e);
@ -506,115 +424,98 @@ where
}
}
fn run_test_nopanic<F>(mut f: F, name: &'static str)
where
F: FnMut(&Allocator),
fn run_test_nopanic<F>(mut f: F)
where F: FnMut(&Allocator)
{
let first_alloc = Allocator::new(usize::MAX, name);
let first_alloc = Allocator::new(usize::MAX);
f(&first_alloc);
}
macro_rules! run_test {
($e:expr) => {
run_test($e, stringify!($e));
};
}
fn main() {
run_test!(|a| dynamic_init(a, false));
run_test!(|a| dynamic_init(a, true));
run_test!(|a| dynamic_drop(a, false));
run_test!(|a| dynamic_drop(a, true));
run_test(|a| dynamic_init(a, false));
run_test(|a| dynamic_init(a, true));
run_test(|a| dynamic_drop(a, false));
run_test(|a| dynamic_drop(a, true));
run_test!(|a| assignment2(a, false, false));
run_test!(|a| assignment2(a, false, true));
run_test!(|a| assignment2(a, true, false));
run_test!(|a| assignment2(a, true, true));
run_test(|a| assignment2(a, false, false));
run_test(|a| assignment2(a, false, true));
run_test(|a| assignment2(a, true, false));
run_test(|a| assignment2(a, true, true));
run_test!(|a| assignment1(a, false));
run_test!(|a| assignment1(a, true));
run_test(|a| assignment1(a, false));
run_test(|a| assignment1(a, true));
run_test!(|a| array_simple(a));
run_test!(|a| vec_simple(a));
run_test!(|a| vec_unreachable(a));
run_test(|a| array_simple(a));
run_test(|a| vec_simple(a));
run_test(|a| vec_unreachable(a));
run_test!(|a| struct_dynamic_drop(a, false, false, false));
run_test!(|a| struct_dynamic_drop(a, false, false, true));
run_test!(|a| struct_dynamic_drop(a, false, true, false));
run_test!(|a| struct_dynamic_drop(a, false, true, true));
run_test!(|a| struct_dynamic_drop(a, true, false, false));
run_test!(|a| struct_dynamic_drop(a, true, false, true));
run_test!(|a| struct_dynamic_drop(a, true, true, false));
run_test!(|a| struct_dynamic_drop(a, true, true, true));
run_test(|a| struct_dynamic_drop(a, false, false, false));
run_test(|a| struct_dynamic_drop(a, false, false, true));
run_test(|a| struct_dynamic_drop(a, false, true, false));
run_test(|a| struct_dynamic_drop(a, false, true, true));
run_test(|a| struct_dynamic_drop(a, true, false, false));
run_test(|a| struct_dynamic_drop(a, true, false, true));
run_test(|a| struct_dynamic_drop(a, true, true, false));
run_test(|a| struct_dynamic_drop(a, true, true, true));
run_test!(|a| field_assignment(a, false));
run_test!(|a| field_assignment(a, true));
run_test(|a| field_assignment(a, false));
run_test(|a| field_assignment(a, true));
run_test!(|a| generator(a, 0));
run_test!(|a| generator(a, 1));
run_test!(|a| generator(a, 2));
run_test!(|a| generator(a, 3));
run_test(|a| generator(a, 0));
run_test(|a| generator(a, 1));
run_test(|a| generator(a, 2));
run_test(|a| generator(a, 3));
run_test!(|a| mixed_drop_and_nondrop(a));
run_test(|a| mixed_drop_and_nondrop(a));
run_test!(|a| slice_pattern_first(a));
run_test!(|a| slice_pattern_middle(a));
run_test!(|a| slice_pattern_two(a));
run_test!(|a| slice_pattern_last(a));
run_test!(|a| slice_pattern_one_of(a, 0));
run_test!(|a| slice_pattern_one_of(a, 1));
run_test!(|a| slice_pattern_one_of(a, 2));
run_test!(|a| slice_pattern_one_of(a, 3));
run_test(|a| slice_pattern_first(a));
run_test(|a| slice_pattern_middle(a));
run_test(|a| slice_pattern_two(a));
run_test(|a| slice_pattern_last(a));
run_test(|a| slice_pattern_one_of(a, 0));
run_test(|a| slice_pattern_one_of(a, 1));
run_test(|a| slice_pattern_one_of(a, 2));
run_test(|a| slice_pattern_one_of(a, 3));
run_test!(|a| subslice_pattern_from_end(a, true));
run_test!(|a| subslice_pattern_from_end(a, false));
run_test!(|a| subslice_pattern_from_end_with_drop(a, true, true));
run_test!(|a| subslice_pattern_from_end_with_drop(a, true, false));
run_test!(|a| subslice_pattern_from_end_with_drop(a, false, true));
run_test!(|a| subslice_pattern_from_end_with_drop(a, false, false));
run_test!(|a| slice_pattern_reassign(a));
run_test!(|a| subslice_pattern_reassign(a));
run_test(|a| subslice_pattern_from_end(a, true));
run_test(|a| subslice_pattern_from_end(a, false));
run_test(|a| subslice_pattern_from_end_with_drop(a, true, true));
run_test(|a| subslice_pattern_from_end_with_drop(a, true, false));
run_test(|a| subslice_pattern_from_end_with_drop(a, false, true));
run_test(|a| subslice_pattern_from_end_with_drop(a, false, false));
run_test(|a| slice_pattern_reassign(a));
run_test(|a| subslice_pattern_reassign(a));
run_test!(|a| index_field_mixed_ends(a));
run_test!(|a| subslice_mixed_min_lengths(a, 0));
run_test!(|a| subslice_mixed_min_lengths(a, 1));
run_test!(|a| subslice_mixed_min_lengths(a, 2));
run_test!(|a| subslice_mixed_min_lengths(a, 3));
run_test!(|a| subslice_mixed_min_lengths(a, 4));
run_test!(|a| subslice_mixed_min_lengths(a, 5));
run_test!(|a| subslice_mixed_min_lengths(a, 6));
run_test!(|a| subslice_mixed_min_lengths(a, 7));
run_test(|a| index_field_mixed_ends(a));
run_test(|a| subslice_mixed_min_lengths(a, 0));
run_test(|a| subslice_mixed_min_lengths(a, 1));
run_test(|a| subslice_mixed_min_lengths(a, 2));
run_test(|a| subslice_mixed_min_lengths(a, 3));
run_test(|a| subslice_mixed_min_lengths(a, 4));
run_test(|a| subslice_mixed_min_lengths(a, 5));
run_test(|a| subslice_mixed_min_lengths(a, 6));
run_test(|a| subslice_mixed_min_lengths(a, 7));
run_test!(|a| move_ref_pattern(a));
run_test(|a| move_ref_pattern(a));
run_test!(|a| {
run_test(|a| {
panic_after_return(a);
});
run_test!(|a| {
run_test(|a| {
panic_after_return_expr(a);
});
run_test!(|a| panic_after_init(a));
run_test!(|a| panic_after_init_temp(a));
run_test!(|a| panic_after_init_by_loop(a));
run_test!(|a| panic_after_init_by_match(a, false));
run_test!(|a| panic_after_init_by_match(a, true));
run_test!(|a| panic_after_init_by_match_with_guard(a, false));
run_test!(|a| panic_after_init_by_match_with_guard(a, true));
run_test!(|a| panic_after_init_by_match_with_bindings_and_guard(a, false));
run_test!(|a| panic_after_init_by_match_with_bindings_and_guard(a, true));
run_test!(|a| panic_after_init_by_match_with_ref_bindings_and_guard(a, false));
run_test!(|a| panic_after_init_by_match_with_ref_bindings_and_guard(a, true));
run_test!(|a| panic_after_init_by_break_if(a, false));
run_test!(|a| panic_after_init_by_break_if(a, true));
run_test(|a| panic_after_init(a));
run_test(|a| panic_after_init_temp(a));
run_test(|a| panic_after_init_by_loop(a));
run_test!(|a| bindings_after_at_dynamic_init_move(a, true));
run_test!(|a| bindings_after_at_dynamic_init_move(a, false));
run_test!(|a| bindings_after_at_dynamic_init_ref(a, true));
run_test!(|a| bindings_after_at_dynamic_init_ref(a, false));
run_test!(|a| bindings_after_at_dynamic_drop_move(a, true));
run_test!(|a| bindings_after_at_dynamic_drop_move(a, false));
run_test!(|a| bindings_after_at_dynamic_drop_ref(a, true));
run_test!(|a| bindings_after_at_dynamic_drop_ref(a, false));
run_test(|a| bindings_after_at_dynamic_init_move(a, true));
run_test(|a| bindings_after_at_dynamic_init_move(a, false));
run_test(|a| bindings_after_at_dynamic_init_ref(a, true));
run_test(|a| bindings_after_at_dynamic_init_ref(a, false));
run_test(|a| bindings_after_at_dynamic_drop_move(a, true));
run_test(|a| bindings_after_at_dynamic_drop_move(a, false));
run_test(|a| bindings_after_at_dynamic_drop_ref(a, true));
run_test(|a| bindings_after_at_dynamic_drop_ref(a, false));
run_test_nopanic(|a| union1(a), "|a| union1(a)");
run_test_nopanic(|a| union1(a));
}

View file

@ -0,0 +1,34 @@
// build-pass
trait Trait { type Item; }
impl<'a, X> Trait for &'a Vec<X> {
type Item = &'a X;
}
impl<X> Trait for Box<dyn Trait<Item = X>> {
type Item = X;
}
fn make_dyn_trait(_: &()) -> Box<dyn Trait<Item = &()>> {
todo!()
}
fn diff<'a, M, N, S>(_: N, _: S)
where
M: 'a,
N: Trait<Item = &'a M>,
S: Trait<Item = &'a M>,
{
todo!()
}
fn may_panic<X>(_: X) { }
fn main() {
let dyn_trait = make_dyn_trait(&());
let storage = vec![()];
let _x = may_panic(());
let storage_ref = &storage;
diff(dyn_trait, storage_ref);
}