Avoid leaking block expression values
This commit is contained in:
parent
7f3e8551dd
commit
4fef39113a
23 changed files with 10934 additions and 10634 deletions
|
@ -3,6 +3,7 @@ use crate::build::ForGuard::OutsideGuard;
|
||||||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||||
use crate::thir::*;
|
use crate::thir::*;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_middle::middle::region;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
|
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
|
||||||
use rustc_session::lint::Level;
|
use rustc_session::lint::Level;
|
||||||
|
@ -12,6 +13,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
crate fn ast_block(
|
crate fn ast_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
scope: Option<region::Scope>,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
ast_block: &'tcx hir::Block<'tcx>,
|
ast_block: &'tcx hir::Block<'tcx>,
|
||||||
source_info: SourceInfo,
|
source_info: SourceInfo,
|
||||||
|
@ -28,9 +30,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
|
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| {
|
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
|
||||||
if targeted_by_break {
|
if targeted_by_break {
|
||||||
this.in_breakable_scope(None, destination, span, |this| {
|
this.in_breakable_scope(None, destination, scope, span, |this| {
|
||||||
Some(this.ast_block_stmts(
|
Some(this.ast_block_stmts(
|
||||||
destination,
|
destination,
|
||||||
|
scope,
|
||||||
block,
|
block,
|
||||||
span,
|
span,
|
||||||
stmts,
|
stmts,
|
||||||
|
@ -39,7 +42,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode)
|
this.ast_block_stmts(destination, scope, block, span, stmts, expr, safety_mode)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -48,6 +51,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
fn ast_block_stmts(
|
fn ast_block_stmts(
|
||||||
&mut self,
|
&mut self,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
scope: Option<region::Scope>,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
span: Span,
|
span: Span,
|
||||||
stmts: Vec<StmtRef<'tcx>>,
|
stmts: Vec<StmtRef<'tcx>>,
|
||||||
|
@ -182,7 +186,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });
|
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });
|
||||||
|
|
||||||
unpack!(block = this.into(destination, block, expr));
|
unpack!(block = this.into(destination, scope, block, expr));
|
||||||
let popped = this.block_context.pop();
|
let popped = this.block_context.pop();
|
||||||
|
|
||||||
assert!(popped.map_or(false, |bf| bf.is_tail_expr()));
|
assert!(popped.map_or(false, |bf| bf.is_tail_expr()));
|
||||||
|
|
|
@ -114,10 +114,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
|
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
|
||||||
this.cfg.push_assign(block, source_info, Place::from(result), box_);
|
this.cfg.push_assign(block, source_info, Place::from(result), box_);
|
||||||
|
|
||||||
// initialize the box contents:
|
// Initialize the box contents. No scope is needed since the
|
||||||
|
// `Box` is already scheduled to be dropped.
|
||||||
unpack!(
|
unpack!(
|
||||||
block =
|
block = this.into(
|
||||||
this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value)
|
this.hir.tcx().mk_place_deref(Place::from(result)),
|
||||||
|
None,
|
||||||
|
block,
|
||||||
|
value,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let result_operand = Operand::Move(Place::from(result));
|
let result_operand = Operand::Move(Place::from(result));
|
||||||
this.record_operands_moved(slice::from_ref(&result_operand));
|
this.record_operands_moved(slice::from_ref(&result_operand));
|
||||||
|
|
|
@ -114,11 +114,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unpack!(block = this.into(temp_place, block, expr));
|
unpack!(block = this.into(temp_place, temp_lifetime, block, expr));
|
||||||
|
|
||||||
if let Some(temp_lifetime) = temp_lifetime {
|
|
||||||
this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
block.and(temp)
|
block.and(temp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
//! See docs in build/expr/mod.rs
|
//! See docs in build/expr/mod.rs
|
||||||
|
|
||||||
use crate::build::expr::category::{Category, RvalueFunc};
|
use crate::build::expr::category::{Category, RvalueFunc};
|
||||||
|
use crate::build::scope::DropKind;
|
||||||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||||
use crate::thir::*;
|
use crate::thir::*;
|
||||||
use rustc_ast::InlineAsmOptions;
|
use rustc_ast::InlineAsmOptions;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_middle::middle::region;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation};
|
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
@ -17,13 +19,19 @@ use std::slice;
|
||||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
/// Compile `expr`, storing the result into `destination`, which
|
/// Compile `expr`, storing the result into `destination`, which
|
||||||
/// is assumed to be uninitialized.
|
/// 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(
|
crate fn into_expr(
|
||||||
&mut self,
|
&mut self,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
scope: Option<region::Scope>,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
expr: Expr<'tcx>,
|
expr: Expr<'tcx>,
|
||||||
) -> BlockAnd<()> {
|
) -> BlockAnd<()> {
|
||||||
debug!("into_expr(destination={:?}, block={:?}, expr={:?})", destination, block, expr);
|
debug!(
|
||||||
|
"into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})",
|
||||||
|
destination, scope, block, expr
|
||||||
|
);
|
||||||
|
|
||||||
// since we frequently have to reference `self` from within a
|
// since we frequently have to reference `self` from within a
|
||||||
// closure, where `self` would be shadowed, it's easier to
|
// closure, where `self` would be shadowed, it's easier to
|
||||||
|
@ -38,6 +46,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
_ => false,
|
_ => 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 {
|
if !expr_is_block_or_scope {
|
||||||
this.block_context.push(BlockFrame::SubExpr);
|
this.block_context.push(BlockFrame::SubExpr);
|
||||||
}
|
}
|
||||||
|
@ -47,15 +63,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let region_scope = (region_scope, source_info);
|
let region_scope = (region_scope, source_info);
|
||||||
ensure_sufficient_stack(|| {
|
ensure_sufficient_stack(|| {
|
||||||
this.in_scope(region_scope, lint_level, |this| {
|
this.in_scope(region_scope, lint_level, |this| {
|
||||||
this.into(destination, block, value)
|
this.into(destination, scope, block, value)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ExprKind::Block { body: ast_block } => {
|
ExprKind::Block { body: ast_block } => {
|
||||||
this.ast_block(destination, block, ast_block, source_info)
|
this.ast_block(destination, scope, block, ast_block, source_info)
|
||||||
}
|
}
|
||||||
ExprKind::Match { scrutinee, arms } => {
|
ExprKind::Match { scrutinee, arms } => {
|
||||||
this.match_expr(destination, expr_span, block, scrutinee, arms)
|
this.match_expr(destination, scope, expr_span, block, scrutinee, arms)
|
||||||
}
|
}
|
||||||
ExprKind::NeverToAny { source } => {
|
ExprKind::NeverToAny { source } => {
|
||||||
let source = this.hir.mirror(source);
|
let source = this.hir.mirror(source);
|
||||||
|
@ -67,6 +83,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
|
||||||
// This is an optimization. If the expression was a call then we already have an
|
// 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.
|
// unreachable block. Don't bother to terminate it and create a new one.
|
||||||
|
schedule_drop(this);
|
||||||
if is_call {
|
if is_call {
|
||||||
block.unit()
|
block.unit()
|
||||||
} else {
|
} else {
|
||||||
|
@ -142,7 +159,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// Start the loop.
|
// Start the loop.
|
||||||
this.cfg.goto(block, source_info, loop_block);
|
this.cfg.goto(block, source_info, loop_block);
|
||||||
|
|
||||||
this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
|
this.in_breakable_scope(
|
||||||
|
Some(loop_block),
|
||||||
|
destination,
|
||||||
|
scope,
|
||||||
|
expr_span,
|
||||||
|
move |this| {
|
||||||
// conduct the test, if necessary
|
// conduct the test, if necessary
|
||||||
let body_block = this.cfg.start_new_block();
|
let body_block = this.cfg.start_new_block();
|
||||||
this.cfg.terminate(
|
this.cfg.terminate(
|
||||||
|
@ -156,12 +178,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// introduce a unit temporary as the destination for the loop body.
|
// introduce a unit temporary as the destination for the loop body.
|
||||||
let tmp = this.get_unit_temp();
|
let tmp = this.get_unit_temp();
|
||||||
// Execute the body, branching back to the test.
|
// Execute the body, branching back to the test.
|
||||||
let body_block_end = unpack!(this.into(tmp, body_block, body));
|
// 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);
|
this.cfg.goto(body_block_end, source_info, loop_block);
|
||||||
|
schedule_drop(this);
|
||||||
|
|
||||||
// Loops are only exited by `break` expressions.
|
// Loops are only exited by `break` expressions.
|
||||||
None
|
None
|
||||||
})
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ExprKind::Call { ty, fun, args, from_hir_call, fn_span } => {
|
ExprKind::Call { ty, fun, args, from_hir_call, fn_span } => {
|
||||||
let intrinsic = match *ty.kind() {
|
let intrinsic = match *ty.kind() {
|
||||||
|
@ -193,8 +219,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
.local_decls
|
.local_decls
|
||||||
.push(LocalDecl::with_source_info(ptr_ty, source_info).internal());
|
.push(LocalDecl::with_source_info(ptr_ty, source_info).internal());
|
||||||
let ptr_temp = Place::from(ptr_temp);
|
let ptr_temp = Place::from(ptr_temp);
|
||||||
let block = unpack!(this.into(ptr_temp, block, ptr));
|
// No need for a scope, ptr_temp doesn't need drop
|
||||||
this.into(this.hir.tcx().mk_place_deref(ptr_temp), block, val)
|
let block = unpack!(this.into(ptr_temp, None, 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)
|
||||||
} else {
|
} else {
|
||||||
let args: Vec<_> = args
|
let args: Vec<_> = args
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -227,10 +259,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.diverge_from(block);
|
this.diverge_from(block);
|
||||||
|
schedule_drop(this);
|
||||||
success.unit()
|
success.unit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Use { source } => this.into(destination, block, source),
|
ExprKind::Use { source } => this.into(destination, scope, block, source),
|
||||||
ExprKind::Borrow { arg, borrow_kind } => {
|
ExprKind::Borrow { arg, borrow_kind } => {
|
||||||
// We don't do this in `as_rvalue` because we use `as_place`
|
// We don't do this in `as_rvalue` because we use `as_place`
|
||||||
// for borrow expressions, so we cannot create an `RValue` that
|
// for borrow expressions, so we cannot create an `RValue` that
|
||||||
|
@ -314,6 +347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
destination,
|
destination,
|
||||||
Rvalue::Aggregate(adt, fields),
|
Rvalue::Aggregate(adt, fields),
|
||||||
);
|
);
|
||||||
|
schedule_drop(this);
|
||||||
block.unit()
|
block.unit()
|
||||||
}
|
}
|
||||||
ExprKind::InlineAsm { template, operands, options, line_spans } => {
|
ExprKind::InlineAsm { template, operands, options, line_spans } => {
|
||||||
|
@ -410,6 +444,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let place = unpack!(block = this.as_place(block, expr));
|
let place = unpack!(block = this.as_place(block, expr));
|
||||||
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
|
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
|
||||||
this.cfg.push_assign(block, source_info, destination, rvalue);
|
this.cfg.push_assign(block, source_info, destination, rvalue);
|
||||||
|
schedule_drop(this);
|
||||||
block.unit()
|
block.unit()
|
||||||
}
|
}
|
||||||
ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => {
|
ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => {
|
||||||
|
@ -427,6 +462,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let place = unpack!(block = this.as_place(block, expr));
|
let place = unpack!(block = this.as_place(block, expr));
|
||||||
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
|
let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place));
|
||||||
this.cfg.push_assign(block, source_info, destination, rvalue);
|
this.cfg.push_assign(block, source_info, destination, rvalue);
|
||||||
|
schedule_drop(this);
|
||||||
block.unit()
|
block.unit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +477,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
|
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
|
||||||
);
|
);
|
||||||
this.generator_drop_cleanup(block);
|
this.generator_drop_cleanup(block);
|
||||||
|
schedule_drop(this);
|
||||||
resume.unit()
|
resume.unit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,6 +509,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
|
||||||
let rvalue = unpack!(block = this.as_local_rvalue(block, expr));
|
let rvalue = unpack!(block = this.as_local_rvalue(block, expr));
|
||||||
this.cfg.push_assign(block, source_info, destination, rvalue);
|
this.cfg.push_assign(block, source_info, destination, rvalue);
|
||||||
|
schedule_drop(this);
|
||||||
block.unit()
|
block.unit()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use crate::build::{BlockAnd, Builder};
|
use crate::build::{BlockAnd, Builder};
|
||||||
use crate::thir::*;
|
use crate::thir::*;
|
||||||
|
use rustc_middle::middle::region;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
|
|
||||||
pub(in crate::build) trait EvalInto<'tcx> {
|
pub(in crate::build) trait EvalInto<'tcx> {
|
||||||
|
@ -13,6 +14,7 @@ pub(in crate::build) trait EvalInto<'tcx> {
|
||||||
self,
|
self,
|
||||||
builder: &mut Builder<'_, 'tcx>,
|
builder: &mut Builder<'_, 'tcx>,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
scope: Option<region::Scope>,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
) -> BlockAnd<()>;
|
) -> BlockAnd<()>;
|
||||||
}
|
}
|
||||||
|
@ -21,13 +23,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
crate fn into<E>(
|
crate fn into<E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
scope: Option<region::Scope>,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
expr: E,
|
expr: E,
|
||||||
) -> BlockAnd<()>
|
) -> BlockAnd<()>
|
||||||
where
|
where
|
||||||
E: EvalInto<'tcx>,
|
E: EvalInto<'tcx>,
|
||||||
{
|
{
|
||||||
expr.eval_into(self, destination, block)
|
expr.eval_into(self, destination, scope, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,10 +39,11 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
|
||||||
self,
|
self,
|
||||||
builder: &mut Builder<'_, 'tcx>,
|
builder: &mut Builder<'_, 'tcx>,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
scope: Option<region::Scope>,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
) -> BlockAnd<()> {
|
) -> BlockAnd<()> {
|
||||||
let expr = builder.hir.mirror(self);
|
let expr = builder.hir.mirror(self);
|
||||||
builder.into_expr(destination, block, expr)
|
builder.into_expr(destination, scope, block, expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +52,9 @@ impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
|
||||||
self,
|
self,
|
||||||
builder: &mut Builder<'_, 'tcx>,
|
builder: &mut Builder<'_, 'tcx>,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
scope: Option<region::Scope>,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
) -> BlockAnd<()> {
|
) -> BlockAnd<()> {
|
||||||
builder.into_expr(destination, block, self)
|
builder.into_expr(destination, scope, block, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
crate fn match_expr(
|
crate fn match_expr(
|
||||||
&mut self,
|
&mut self,
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
|
destination_scope: Option<region::Scope>,
|
||||||
span: Span,
|
span: Span,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
scrutinee: ExprRef<'tcx>,
|
scrutinee: ExprRef<'tcx>,
|
||||||
|
@ -107,6 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
|
||||||
self.lower_match_arms(
|
self.lower_match_arms(
|
||||||
destination,
|
destination,
|
||||||
|
destination_scope,
|
||||||
scrutinee_place,
|
scrutinee_place,
|
||||||
scrutinee_span,
|
scrutinee_span,
|
||||||
arm_candidates,
|
arm_candidates,
|
||||||
|
@ -213,75 +215,13 @@ 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.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
|
/// Binds the variables and ascribes types for a given `match` arm or
|
||||||
/// `let` binding.
|
/// `let` binding.
|
||||||
///
|
///
|
||||||
/// Also check if the guard matches, if it's provided.
|
/// Also check if the guard matches, if it's provided.
|
||||||
/// `arm_scope` should be `Some` if and only if this is called for a
|
/// `arm_scope` should be `Some` if and only if this is called for a
|
||||||
/// `match` arm.
|
/// `match` arm.
|
||||||
fn bind_pattern(
|
crate fn bind_pattern(
|
||||||
&mut self,
|
&mut self,
|
||||||
outer_source_info: SourceInfo,
|
outer_source_info: SourceInfo,
|
||||||
candidate: Candidate<'_, 'tcx>,
|
candidate: Candidate<'_, 'tcx>,
|
||||||
|
@ -365,13 +305,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
|
PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
|
||||||
let place =
|
let place =
|
||||||
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
|
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
|
||||||
unpack!(block = self.into(place, block, initializer));
|
let region_scope = self.hir.region_scope_tree.var_scope(var.local_id);
|
||||||
|
|
||||||
|
unpack!(block = self.into(place, Some(region_scope), block, initializer));
|
||||||
|
|
||||||
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
|
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
|
||||||
let source_info = self.source_info(irrefutable_pat.span);
|
let source_info = self.source_info(irrefutable_pat.span);
|
||||||
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForLet, place);
|
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForLet, place);
|
||||||
|
|
||||||
self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
|
|
||||||
block.unit()
|
block.unit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,9 +339,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
ascription:
|
ascription:
|
||||||
thir::pattern::Ascription { user_ty: pat_ascription_ty, variance: _, user_ty_span },
|
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 =
|
let place =
|
||||||
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
|
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
|
||||||
unpack!(block = self.into(place, block, initializer));
|
unpack!(block = self.into(place, Some(region_scope), block, initializer));
|
||||||
|
|
||||||
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
|
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
|
||||||
let pattern_source_info = self.source_info(irrefutable_pat.span);
|
let pattern_source_info = self.source_info(irrefutable_pat.span);
|
||||||
|
@ -438,7 +380,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
|
|
||||||
block.unit()
|
block.unit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +625,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Candidate<'pat, 'tcx> {
|
pub(super) struct Candidate<'pat, 'tcx> {
|
||||||
/// `Span` of the original pattern that gave rise to this candidate
|
/// `Span` of the original pattern that gave rise to this candidate
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
||||||
|
@ -1394,12 +1335,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
match test.kind {
|
match test.kind {
|
||||||
TestKind::SwitchInt { switch_ty, ref mut options } => {
|
TestKind::SwitchInt { switch_ty, ref mut options } => {
|
||||||
for candidate in candidates.iter() {
|
for candidate in candidates.iter() {
|
||||||
if !self.add_cases_to_switch(
|
if !self.add_cases_to_switch(&match_place, candidate, switch_ty, options) {
|
||||||
&match_place,
|
|
||||||
candidate,
|
|
||||||
switch_ty,
|
|
||||||
options,
|
|
||||||
) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1780,14 +1716,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// and that is clearly not correct.
|
// and that is clearly not correct.
|
||||||
let by_value_bindings =
|
let by_value_bindings = parent_bindings
|
||||||
parent_bindings
|
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(bindings, _)| bindings)
|
.flat_map(|(bindings, _)| bindings)
|
||||||
.chain(&candidate.bindings)
|
.chain(&candidate.bindings)
|
||||||
.filter(|binding| {
|
.filter(|binding| matches!(binding.binding_mode, BindingMode::ByValue));
|
||||||
matches!(binding.binding_mode, BindingMode::ByValue )
|
|
||||||
});
|
|
||||||
// Read all of the by reference bindings to ensure that the
|
// Read all of the by reference bindings to ensure that the
|
||||||
// place they refer to can't be modified by the guard.
|
// place they refer to can't be modified by the guard.
|
||||||
for binding in by_value_bindings.clone() {
|
for binding in by_value_bindings.clone() {
|
||||||
|
|
|
@ -75,7 +75,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||||
kind: hir::TraitItemKind::Const(ty, Some(body_id)),
|
kind: hir::TraitItemKind::Const(ty, Some(body_id)),
|
||||||
..
|
..
|
||||||
}) => (*body_id, ty.span, None),
|
}) => (*body_id, ty.span, None),
|
||||||
Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => (*body, tcx.hir().span(*hir_id), None),
|
Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => {
|
||||||
|
(*body, tcx.hir().span(*hir_id), None)
|
||||||
|
}
|
||||||
|
|
||||||
_ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def.did),
|
_ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def.did),
|
||||||
};
|
};
|
||||||
|
@ -183,7 +185,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
||||||
return_ty,
|
return_ty,
|
||||||
return_ty_span,
|
return_ty_span,
|
||||||
body,
|
body,
|
||||||
span_with_body
|
span_with_body,
|
||||||
);
|
);
|
||||||
mir.yield_ty = yield_ty;
|
mir.yield_ty = yield_ty;
|
||||||
mir
|
mir
|
||||||
|
@ -581,7 +583,7 @@ fn construct_fn<'a, 'tcx, A>(
|
||||||
return_ty: Ty<'tcx>,
|
return_ty: Ty<'tcx>,
|
||||||
return_ty_span: Span,
|
return_ty_span: Span,
|
||||||
body: &'tcx hir::Body<'tcx>,
|
body: &'tcx hir::Body<'tcx>,
|
||||||
span_with_body: Span
|
span_with_body: Span,
|
||||||
) -> Body<'tcx>
|
) -> Body<'tcx>
|
||||||
where
|
where
|
||||||
A: Iterator<Item = ArgInfo<'tcx>>,
|
A: Iterator<Item = ArgInfo<'tcx>>,
|
||||||
|
@ -615,8 +617,12 @@ where
|
||||||
let arg_scope_s = (arg_scope, source_info);
|
let arg_scope_s = (arg_scope, source_info);
|
||||||
// Attribute epilogue to function's closing brace
|
// Attribute epilogue to function's closing brace
|
||||||
let fn_end = span_with_body.shrink_to_hi();
|
let fn_end = span_with_body.shrink_to_hi();
|
||||||
let return_block =
|
let return_block = unpack!(builder.in_breakable_scope(
|
||||||
unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
|
None,
|
||||||
|
Place::return_place(),
|
||||||
|
Some(call_site_scope),
|
||||||
|
fn_end,
|
||||||
|
|builder| {
|
||||||
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
|
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
|
||||||
builder.args_and_body(
|
builder.args_and_body(
|
||||||
START_BLOCK,
|
START_BLOCK,
|
||||||
|
@ -626,11 +632,13 @@ where
|
||||||
&body.value,
|
&body.value,
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
}));
|
},
|
||||||
|
));
|
||||||
let source_info = builder.source_info(fn_end);
|
let source_info = builder.source_info(fn_end);
|
||||||
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
|
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
|
||||||
let should_abort = should_abort_on_panic(tcx, fn_def_id, abi);
|
let should_abort = should_abort_on_panic(tcx, fn_def_id, abi);
|
||||||
builder.build_drop_trees(should_abort);
|
builder.build_drop_trees(should_abort);
|
||||||
|
builder.unschedule_return_place_drop();
|
||||||
return_block.unit()
|
return_block.unit()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -657,12 +665,15 @@ fn construct_const<'a, 'tcx>(
|
||||||
let owner_id = tcx.hir().body_owner(body_id);
|
let owner_id = tcx.hir().body_owner(body_id);
|
||||||
let def_id = tcx.hir().local_def_id(owner_id);
|
let def_id = tcx.hir().local_def_id(owner_id);
|
||||||
let span = tcx.hir().span(owner_id);
|
let span = tcx.hir().span(owner_id);
|
||||||
let mut builder = Builder::new(hir, def_id.to_def_id(), span, 0, Safety::Safe, const_ty, const_ty_span, None);
|
let mut builder =
|
||||||
|
Builder::new(hir, def_id.to_def_id(), span, 0, Safety::Safe, const_ty, const_ty_span, None);
|
||||||
|
|
||||||
let mut block = START_BLOCK;
|
let mut block = START_BLOCK;
|
||||||
let ast_expr = &tcx.hir().body(body_id).value;
|
let ast_expr = &tcx.hir().body(body_id).value;
|
||||||
let expr = builder.hir.mirror(ast_expr);
|
let expr = builder.hir.mirror(ast_expr);
|
||||||
unpack!(block = builder.into_expr(Place::return_place(), block, 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));
|
||||||
|
|
||||||
let source_info = builder.source_info(span);
|
let source_info = builder.source_info(span);
|
||||||
builder.cfg.terminate(block, source_info, TerminatorKind::Return);
|
builder.cfg.terminate(block, source_info, TerminatorKind::Return);
|
||||||
|
@ -697,7 +708,8 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
|
||||||
hir::BodyOwnerKind::Const => 0,
|
hir::BodyOwnerKind::Const => 0,
|
||||||
hir::BodyOwnerKind::Static(_) => 0,
|
hir::BodyOwnerKind::Static(_) => 0,
|
||||||
};
|
};
|
||||||
let mut builder = Builder::new(hir, def_id.to_def_id(), span, num_params, Safety::Safe, ty, span, None);
|
let mut builder =
|
||||||
|
Builder::new(hir, def_id.to_def_id(), span, num_params, Safety::Safe, ty, span, None);
|
||||||
let source_info = builder.source_info(span);
|
let source_info = builder.source_info(span);
|
||||||
// Some MIR passes will expect the number of parameters to match the
|
// Some MIR passes will expect the number of parameters to match the
|
||||||
// function declaration.
|
// function declaration.
|
||||||
|
@ -941,7 +953,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = self.hir.mirror(ast_body);
|
let body = self.hir.mirror(ast_body);
|
||||||
self.into(Place::return_place(), block, 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_correct_source_scope_for_arg(
|
fn set_correct_source_scope_for_arg(
|
||||||
|
|
|
@ -81,8 +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::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG};
|
||||||
use crate::thir::{Expr, ExprRef, LintLevel};
|
use crate::thir::{Arm, Expr, ExprRef, LintLevel};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
|
@ -156,6 +157,8 @@ struct BreakableScope<'tcx> {
|
||||||
/// The destination of the loop/block expression itself (i.e., where to put
|
/// The destination of the loop/block expression itself (i.e., where to put
|
||||||
/// the result of a `break` or `return` expression)
|
/// the result of a `break` or `return` expression)
|
||||||
break_destination: Place<'tcx>,
|
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.
|
/// Drops that happen on the `break`/`return` path.
|
||||||
break_drops: DropTree,
|
break_drops: DropTree,
|
||||||
/// Drops that happen on the `continue` path.
|
/// Drops that happen on the `continue` path.
|
||||||
|
@ -438,6 +441,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
loop_block: Option<BasicBlock>,
|
loop_block: Option<BasicBlock>,
|
||||||
break_destination: Place<'tcx>,
|
break_destination: Place<'tcx>,
|
||||||
|
destination_scope: Option<region::Scope>,
|
||||||
span: Span,
|
span: Span,
|
||||||
f: F,
|
f: F,
|
||||||
) -> BlockAnd<()>
|
) -> BlockAnd<()>
|
||||||
|
@ -448,15 +452,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let scope = BreakableScope {
|
let scope = BreakableScope {
|
||||||
region_scope,
|
region_scope,
|
||||||
break_destination,
|
break_destination,
|
||||||
|
destination_scope,
|
||||||
break_drops: DropTree::new(),
|
break_drops: DropTree::new(),
|
||||||
continue_drops: loop_block.map(|_| 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);
|
self.scopes.breakable_scopes.push(scope);
|
||||||
let normal_exit_block = f(self);
|
let normal_exit_block = f(self);
|
||||||
let breakable_scope = self.scopes.breakable_scopes.pop().unwrap();
|
let breakable_scope = self.scopes.breakable_scopes.pop().unwrap();
|
||||||
assert!(breakable_scope.region_scope == region_scope);
|
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);
|
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) {
|
match (normal_exit_block, break_block) {
|
||||||
(Some(block), None) | (None, Some(block)) => block,
|
(Some(block), None) | (None, Some(block)) => block,
|
||||||
(None, None) => self.cfg.start_new_block().unit(),
|
(None, None) => self.cfg.start_new_block().unit(),
|
||||||
|
@ -585,22 +593,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
.rposition(|breakable_scope| breakable_scope.region_scope == scope)
|
.rposition(|breakable_scope| breakable_scope.region_scope == scope)
|
||||||
.unwrap_or_else(|| span_bug!(span, "no enclosing breakable scope found"))
|
.unwrap_or_else(|| span_bug!(span, "no enclosing breakable scope found"))
|
||||||
};
|
};
|
||||||
let (break_index, destination) = match target {
|
let (break_index, destination, dest_scope) = match target {
|
||||||
BreakableTarget::Return => {
|
BreakableTarget::Return => {
|
||||||
let scope = &self.scopes.breakable_scopes[0];
|
let scope = &self.scopes.breakable_scopes[0];
|
||||||
if scope.break_destination != Place::return_place() {
|
if scope.break_destination != Place::return_place() {
|
||||||
span_bug!(span, "`return` in item with no return scope");
|
span_bug!(span, "`return` in item with no return scope");
|
||||||
}
|
}
|
||||||
(0, Some(scope.break_destination))
|
(0, Some(scope.break_destination), scope.destination_scope)
|
||||||
}
|
}
|
||||||
BreakableTarget::Break(scope) => {
|
BreakableTarget::Break(scope) => {
|
||||||
let break_index = get_scope_index(scope);
|
let break_index = get_scope_index(scope);
|
||||||
let scope = &self.scopes.breakable_scopes[break_index];
|
let scope = &self.scopes.breakable_scopes[break_index];
|
||||||
(break_index, Some(scope.break_destination))
|
(break_index, Some(scope.break_destination), scope.destination_scope)
|
||||||
}
|
}
|
||||||
BreakableTarget::Continue(scope) => {
|
BreakableTarget::Continue(scope) => {
|
||||||
let break_index = get_scope_index(scope);
|
let break_index = get_scope_index(scope);
|
||||||
(break_index, None)
|
(break_index, None, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -608,7 +616,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
debug!("stmt_expr Break val block_context.push(SubExpr)");
|
debug!("stmt_expr Break val block_context.push(SubExpr)");
|
||||||
self.block_context.push(BlockFrame::SubExpr);
|
self.block_context.push(BlockFrame::SubExpr);
|
||||||
unpack!(block = self.into(destination, block, value));
|
unpack!(block = self.into(destination, dest_scope, block, value));
|
||||||
|
dest_scope
|
||||||
|
.map(|scope| self.unschedule_drop(scope, destination.as_local().unwrap()));
|
||||||
self.block_context.pop();
|
self.block_context.pop();
|
||||||
} else {
|
} else {
|
||||||
self.cfg.push_assign_unit(block, source_info, destination, self.hir.tcx())
|
self.cfg.push_assign_unit(block, source_info, destination, self.hir.tcx())
|
||||||
|
@ -858,14 +868,47 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
span_bug!(span, "region scope {:?} not in scope to drop {:?}", region_scope, local);
|
span_bug!(span, "region scope {:?} not in scope to drop {:?}", region_scope, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates that the "local operand" stored in `local` is
|
/// 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
|
||||||
/// *moved* at some point during execution (see `local_scope` for
|
/// *moved* at some point during execution (see `local_scope` for
|
||||||
/// more information about what a "local operand" is -- in short,
|
/// more information about what a "local operand" is -- in short,
|
||||||
/// it's an intermediate operand created as part of preparing some
|
/// it's an intermediate operand created as part of preparing some
|
||||||
/// MIR instruction). We use this information to suppress
|
/// MIR instruction). We use this information to suppress
|
||||||
/// redundant drops on the non-unwind paths. This results in less
|
/// redundant drops. This results in less MIR, but also avoids spurious
|
||||||
/// MIR, but also avoids spurious borrow check errors
|
/// borrow check errors (c.f. #64391).
|
||||||
/// (c.f. #64391).
|
|
||||||
///
|
///
|
||||||
/// Example: when compiling the call to `foo` here:
|
/// Example: when compiling the call to `foo` here:
|
||||||
///
|
///
|
||||||
|
@ -1116,11 +1159,96 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
success_block
|
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.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.
|
/// Unschedules any drops in the top scope.
|
||||||
///
|
///
|
||||||
/// This is only needed for `match` arm scopes, because they have one
|
/// This is only needed for `match` arm scopes, because they have one
|
||||||
/// entrance per pattern, but only one exit.
|
/// entrance per pattern, but only one exit.
|
||||||
crate fn clear_top_scope(&mut self, region_scope: region::Scope) {
|
pub(super) fn clear_top_scope(&mut self, region_scope: region::Scope) {
|
||||||
let top_scope = self.scopes.scopes.last_mut().unwrap();
|
let top_scope = self.scopes.scopes.last_mut().unwrap();
|
||||||
|
|
||||||
assert_eq!(top_scope.region_scope, region_scope);
|
assert_eq!(top_scope.region_scope, region_scope);
|
||||||
|
@ -1128,6 +1256,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
top_scope.drops.clear();
|
top_scope.drops.clear();
|
||||||
top_scope.invalidate_cache();
|
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`.
|
/// Builds drops for `pop_scope` and `leave_top_scope`.
|
||||||
|
@ -1203,20 +1343,24 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
||||||
/// Build a drop tree for a breakable scope.
|
/// Build a drop tree for a breakable scope.
|
||||||
///
|
///
|
||||||
/// If `continue_block` is `Some`, then the tree is for `continue` inside a
|
/// If `continue_block` is `Some`, then the tree is for `continue` inside a
|
||||||
/// loop. Otherwise this is for `break` or `return`.
|
/// 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.
|
||||||
fn build_exit_tree(
|
fn build_exit_tree(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut drops: DropTree,
|
mut drops: DropTree,
|
||||||
continue_block: Option<BasicBlock>,
|
continue_block: Option<(BasicBlock, DropIdx)>,
|
||||||
) -> Option<BlockAnd<()>> {
|
) -> Option<BlockAnd<()>> {
|
||||||
let mut blocks = IndexVec::from_elem(None, &drops.drops);
|
let mut blocks = IndexVec::from_elem(None, &drops.drops);
|
||||||
blocks[ROOT_NODE] = continue_block;
|
blocks[ROOT_NODE] = continue_block.map(|(block, _)| block);
|
||||||
|
|
||||||
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
|
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
|
||||||
|
|
||||||
// Link the exit drop tree to unwind drop tree.
|
// Link the exit drop tree to unwind drop tree.
|
||||||
if drops.drops.iter().any(|(drop, _)| drop.kind == DropKind::Value) {
|
if drops.drops.iter().any(|(drop, _)| drop.kind == DropKind::Value) {
|
||||||
let unwind_target = self.diverge_cleanup();
|
let unwind_target = continue_block
|
||||||
|
.map_or_else(|| self.diverge_cleanup(), |(_, unwind_target)| unwind_target);
|
||||||
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
|
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
|
||||||
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) {
|
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) {
|
||||||
match drop_data.0.kind {
|
match drop_data.0.kind {
|
||||||
|
|
|
@ -1772,7 +1772,7 @@ fn test_append_drop_leak() {
|
||||||
|
|
||||||
catch_unwind(move || left.append(&mut right)).unwrap_err();
|
catch_unwind(move || left.append(&mut right)).unwrap_err();
|
||||||
|
|
||||||
assert_eq!(DROPS.load(SeqCst), 4); // Rust issue #47949 ate one little piggy
|
assert_eq!(DROPS.load(SeqCst), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -5,18 +5,19 @@
|
||||||
let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:21:12: 21:12
|
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 _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 _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 _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
|
+ 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
|
+ 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 _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 _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 _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 _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 {
|
+ scope 2 {
|
||||||
+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:22:5: 22:22
|
+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:22:5: 22:22
|
||||||
+ scope 3 {
|
+ scope 3 {
|
||||||
+ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:22:5: 22:22
|
+ debug b => _7; // 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 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
|
+ scope 7 (inlined sleep) { // at $DIR/inline-diverging.rs:22:5: 22:22
|
||||||
|
@ -40,12 +41,12 @@
|
||||||
- // mir::Constant
|
- // mir::Constant
|
||||||
// + span: $DIR/inline-diverging.rs:22:16: 22:21
|
// + span: $DIR/inline-diverging.rs:22:16: 22:21
|
||||||
// + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) }
|
// + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) }
|
||||||
+ StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
|
+ StorageLive(_7); // 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(_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
|
+ 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
|
+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
|
||||||
+ StorageLive(_7); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
|
+ StorageLive(_8); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
|
||||||
+ _7 = const (); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
|
+ _8 = 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
|
+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:22:5: 22:22
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn test() -> Option<Box<u32>> {
|
||||||
StorageLive(_3); // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
|
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
|
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
|
_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: bb9]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
|
_3 = <Option<u32> as Try>::into_result(move _4) -> [return: bb1, unwind: bb10]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/issue-62289.rs:9:15: 9:20
|
// + 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>)) }
|
// + 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>)) }
|
||||||
|
@ -65,7 +65,7 @@ fn test() -> Option<Box<u32>> {
|
||||||
StorageLive(_8); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
|
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
|
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
|
_9 = _6; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
|
||||||
_8 = <NoneError as From<NoneError>>::from(move _9) -> [return: bb5, unwind: bb9]; // 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
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/issue-62289.rs:9:19: 9:20
|
// + 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>)) }
|
// + 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 +73,7 @@ fn test() -> Option<Box<u32>> {
|
||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
StorageDead(_9); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
|
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: bb9]; // scope 2 at $DIR/issue-62289.rs:9:15: 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
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/issue-62289.rs:9:15: 9:20
|
// + 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>)) }
|
// + 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,7 +82,7 @@ fn test() -> Option<Box<u32>> {
|
||||||
bb6: {
|
bb6: {
|
||||||
StorageDead(_8); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
|
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
|
StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
|
||||||
drop(_2) -> bb7; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
|
drop(_2) -> [return: bb7, unwind: bb9]; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
|
||||||
}
|
}
|
||||||
|
|
||||||
bb7: {
|
bb7: {
|
||||||
|
@ -97,10 +97,14 @@ fn test() -> Option<Box<u32>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb9 (cleanup): {
|
bb9 (cleanup): {
|
||||||
drop(_2) -> bb10; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
|
drop(_0) -> bb11; // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
|
||||||
}
|
}
|
||||||
|
|
||||||
bb10 (cleanup): {
|
bb10 (cleanup): {
|
||||||
|
drop(_2) -> bb11; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
|
||||||
|
}
|
||||||
|
|
||||||
|
bb11 (cleanup): {
|
||||||
resume; // scope 0 at $DIR/issue-62289.rs:8:1: 10:2
|
resume; // scope 0 at $DIR/issue-62289.rs:8:1: 10:2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,12 @@
|
||||||
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||||
19| 2|}
|
19| 2|}
|
||||||
------------------
|
------------------
|
||||||
| 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) {
|
| 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);
|
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||||
| 19| 1|}
|
| 19| 1|}
|
||||||
------------------
|
------------------
|
||||||
| 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) {
|
| 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);
|
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||||
| 19| 1|}
|
| 19| 1|}
|
||||||
|
|
|
@ -28,18 +28,16 @@ Counter in file 0 79:14 -> 79:16, 0
|
||||||
Counter in file 0 81:1 -> 81:2, 0
|
Counter in file 0 81:1 -> 81:2, 0
|
||||||
Counter in file 0 91:25 -> 91:34, 0
|
Counter in file 0 91:25 -> 91:34, 0
|
||||||
Counter in file 0 5:1 -> 5:25, #1
|
Counter in file 0 5:1 -> 5:25, #1
|
||||||
Counter in file 0 21:1 -> 21:23, #1
|
|
||||||
Counter in file 0 17:20 -> 17:21, #1
|
|
||||||
Counter in file 0 67:5 -> 67:23, #1
|
|
||||||
Counter in file 0 38:1 -> 38:19, #1
|
|
||||||
Counter in file 0 13:20 -> 13:21, #1
|
|
||||||
Counter in file 0 29:1 -> 29:22, #1
|
|
||||||
Counter in file 0 93:1 -> 101:2, #1
|
|
||||||
Counter in file 0 91:1 -> 91:25, #1
|
|
||||||
Counter in file 0 5:25 -> 6:14, #1
|
Counter in file 0 5:25 -> 6:14, #1
|
||||||
Counter in file 0 7:9 -> 7:10, #2
|
Counter in file 0 7:9 -> 7:10, #2
|
||||||
Counter in file 0 9:9 -> 9:10, (#1 - #2)
|
Counter in file 0 9:9 -> 9:10, (#1 - #2)
|
||||||
Counter in file 0 11:1 -> 11:2, (#2 + (#1 - #2))
|
Counter in file 0 11:1 -> 11:2, (#2 + (#1 - #2))
|
||||||
|
Counter in file 0 21:1 -> 21:23, #1
|
||||||
|
Counter in file 0 67:5 -> 67:23, #1
|
||||||
|
Counter in file 0 38:1 -> 38:19, #1
|
||||||
|
Counter in file 0 29:1 -> 29:22, #1
|
||||||
|
Counter in file 0 93:1 -> 101:2, #1
|
||||||
|
Counter in file 0 91:1 -> 91:25, #1
|
||||||
Counter in file 0 38:19 -> 42:12, #1
|
Counter in file 0 38:19 -> 42:12, #1
|
||||||
Counter in file 0 43:9 -> 43:10, #3
|
Counter in file 0 43:9 -> 43:10, #3
|
||||||
Counter in file 0 43:14 -> 43:18, (#1 + 0)
|
Counter in file 0 43:14 -> 43:18, (#1 + 0)
|
||||||
|
@ -55,6 +53,7 @@ Counter in file 0 51:5 -> 52:18, #1
|
||||||
Counter in file 0 53:13 -> 53:14, #2
|
Counter in file 0 53:13 -> 53:14, #2
|
||||||
Counter in file 0 63:13 -> 63:14, (#1 - #2)
|
Counter in file 0 63:13 -> 63:14, (#1 - #2)
|
||||||
Counter in file 0 65:5 -> 65:6, (#2 + (#1 - #2))
|
Counter in file 0 65:5 -> 65:6, (#2 + (#1 - #2))
|
||||||
|
Counter in file 0 13:20 -> 13:21, #1
|
||||||
Counter in file 0 49:1 -> 68:12, #1
|
Counter in file 0 49:1 -> 68:12, #1
|
||||||
Counter in file 0 69:9 -> 69:10, #2
|
Counter in file 0 69:9 -> 69:10, #2
|
||||||
Counter in file 0 69:14 -> 69:27, (#1 + 0)
|
Counter in file 0 69:14 -> 69:27, (#1 + 0)
|
||||||
|
@ -70,6 +69,7 @@ Counter in file 0 86:14 -> 86:16, #2
|
||||||
Counter in file 0 87:14 -> 87:16, #3
|
Counter in file 0 87:14 -> 87:16, #3
|
||||||
Counter in file 0 89:1 -> 89:2, (#3 + (#2 + (#1 - (#3 + #2))))
|
Counter in file 0 89:1 -> 89:2, (#3 + (#2 + (#1 - (#3 + #2))))
|
||||||
Counter in file 0 17:1 -> 17:20, #1
|
Counter in file 0 17:1 -> 17:20, #1
|
||||||
|
Counter in file 0 17:20 -> 17:21, #1
|
||||||
Counter in file 0 66:5 -> 66:23, #1
|
Counter in file 0 66:5 -> 66:23, #1
|
||||||
Counter in file 0 17:9 -> 17:10, #1
|
Counter in file 0 17:9 -> 17:10, #1
|
||||||
Counter in file 0 17:9 -> 17:10, #1
|
Counter in file 0 17:9 -> 17:10, #1
|
||||||
|
|
|
@ -32,12 +32,12 @@ Combined regions:
|
||||||
10:5 -> 12:6 (count=1)
|
10:5 -> 12:6 (count=1)
|
||||||
Segment at 10:5 (count = 1), RegionEntry
|
Segment at 10:5 (count = 1), RegionEntry
|
||||||
Segment at 12:6 (count = 0), Skipped
|
Segment at 12:6 (count = 0), Skipped
|
||||||
Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworklENtNtNtCs3rFBWs28XFJ_4core3ops4drop4Drop4dropB4_
|
Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworklENtNtNtCs6HRHKMTmAen_4core3ops4drop4Drop4dropB4_
|
||||||
Combined regions:
|
Combined regions:
|
||||||
17:5 -> 19:6 (count=1)
|
17:5 -> 19:6 (count=1)
|
||||||
Segment at 17:5 (count = 1), RegionEntry
|
Segment at 17:5 (count = 1), RegionEntry
|
||||||
Segment at 19:6 (count = 0), Skipped
|
Segment at 19:6 (count = 0), Skipped
|
||||||
Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworkdENtNtNtCs3rFBWs28XFJ_4core3ops4drop4Drop4dropB4_
|
Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworkdENtNtNtCs6HRHKMTmAen_4core3ops4drop4Drop4dropB4_
|
||||||
Combined regions:
|
Combined regions:
|
||||||
17:5 -> 19:6 (count=1)
|
17:5 -> 19:6 (count=1)
|
||||||
Segment at 17:5 (count = 1), RegionEntry
|
Segment at 17:5 (count = 1), RegionEntry
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Counter in file 0 17:1 -> 19:2, #1
|
|
||||||
Counter in file 0 25:1 -> 27:2, #1
|
Counter in file 0 25:1 -> 27:2, #1
|
||||||
Counter in file 0 17:1 -> 19:2, #1
|
Counter in file 0 17:1 -> 19:2, #1
|
||||||
|
Counter in file 0 17:1 -> 19:2, #1
|
||||||
Counter in file 0 5:1 -> 12:2, #1
|
Counter in file 0 5:1 -> 12:2, #1
|
||||||
Counter in file 0 17:1 -> 19:2, 0
|
Counter in file 0 17:1 -> 19:2, 0
|
||||||
Counter in file 0 33:1 -> 35:2, 0
|
Counter in file 0 33:1 -> 35:2, 0
|
||||||
|
@ -78,17 +78,17 @@ Segment at 51:1 (count = 0), RegionEntry
|
||||||
Segment at 51:2 (count = 0), Skipped
|
Segment at 51:2 (count = 0), Skipped
|
||||||
Segment at 53:1 (count = 1), RegionEntry
|
Segment at 53:1 (count = 1), RegionEntry
|
||||||
Segment at 61:2 (count = 0), Skipped
|
Segment at 61:2 (count = 0), Skipped
|
||||||
|
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionRINtNtCsFAjihUSTht_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate
|
||||||
|
Combined regions:
|
||||||
|
17:1 -> 19:2 (count=1)
|
||||||
|
Segment at 17:1 (count = 1), RegionEntry
|
||||||
|
Segment at 19:2 (count = 0), Skipped
|
||||||
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionReECs4fqI2P2rA04_10uses_crate
|
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionReECs4fqI2P2rA04_10uses_crate
|
||||||
Combined regions:
|
Combined regions:
|
||||||
17:1 -> 19:2 (count=1)
|
17:1 -> 19:2 (count=1)
|
||||||
Segment at 17:1 (count = 1), RegionEntry
|
Segment at 17:1 (count = 1), RegionEntry
|
||||||
Segment at 19:2 (count = 0), Skipped
|
Segment at 19:2 (count = 0), Skipped
|
||||||
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionRINtNtCs3QflaznQylx_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate
|
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate46used_only_from_this_lib_crate_generic_functionINtNtCsFAjihUSTht_5alloc3vec3VeclEEB2_
|
||||||
Combined regions:
|
|
||||||
17:1 -> 19:2 (count=1)
|
|
||||||
Segment at 17:1 (count = 1), RegionEntry
|
|
||||||
Segment at 19:2 (count = 0), Skipped
|
|
||||||
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate46used_only_from_this_lib_crate_generic_functionINtNtCs3QflaznQylx_5alloc3vec3VeclEEB2_
|
|
||||||
Combined regions:
|
Combined regions:
|
||||||
21:1 -> 23:2 (count=1)
|
21:1 -> 23:2 (count=1)
|
||||||
Segment at 21:1 (count = 1), RegionEntry
|
Segment at 21:1 (count = 1), RegionEntry
|
||||||
|
@ -98,7 +98,7 @@ Combined regions:
|
||||||
21:1 -> 23:2 (count=1)
|
21:1 -> 23:2 (count=1)
|
||||||
Segment at 21:1 (count = 1), RegionEntry
|
Segment at 21:1 (count = 1), RegionEntry
|
||||||
Segment at 23:2 (count = 0), Skipped
|
Segment at 23:2 (count = 0), Skipped
|
||||||
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate50used_from_bin_crate_and_lib_crate_generic_functionINtNtCs3QflaznQylx_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate
|
Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate50used_from_bin_crate_and_lib_crate_generic_functionINtNtCsFAjihUSTht_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate
|
||||||
Combined regions:
|
Combined regions:
|
||||||
25:1 -> 27:2 (count=1)
|
25:1 -> 27:2 (count=1)
|
||||||
Segment at 25:1 (count = 1), RegionEntry
|
Segment at 25:1 (count = 1), RegionEntry
|
||||||
|
|
|
@ -70,166 +70,166 @@ For revisions in Pull Requests (PR):
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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 = &mut _1
|
<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 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"><span class="annotation">@0,1,2,3,4,5⦊</span>pub fn block_on<F: Future>(mut future: F) -> F::Output {</span></span>
|
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"><span class="annotation">@0,1,2,3,4,5⦊</span>pub fn block_on<F: Future>(mut future: F) -> F::Output {</span></span>
|
||||||
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let mut future = unsafe { Pin::new_unchecked(&mut future) };</span></span>
|
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let mut future = unsafe { Pin::new_unchecked(&mut future) };</span></span>
|
||||||
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"></span></span>
|
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 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> static VTABLE: RawWakerVTable = RawWakerVTable::new(</span></span>
|
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 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| unimplemented!("clone"),</span></span>
|
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 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| unimplemented!("wake"),</span></span>
|
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 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| unimplemented!("wake_by_ref"),</span></span>
|
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 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> |_| (),</span></span>
|
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 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> );</span></span>
|
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 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };</span></span>
|
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) };</span></span>
|
||||||
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
<span class="line"><span class="code even" style="--layer: 1" title="111:54-111:65: @0[2]: _3 = &mut _1
|
||||||
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb20]
|
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb23]
|
||||||
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
|
||||||
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb20]
|
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb23]
|
||||||
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
|
||||||
119:79-119:86: @2[4]: _8 = &(*_9)
|
119:79-119:86: @2[4]: _8 = &(*_9)
|
||||||
119:79-119:86: @2[5]: _7 = &(*_8)
|
119:79-119:86: @2[5]: _7 = &(*_8)
|
||||||
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb20]
|
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb23]
|
||||||
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb20]
|
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb23]
|
||||||
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
|
||||||
120:47-120:53: @4[7]: _12 = &_4
|
120:47-120:53: @4[7]: _12 = &_4
|
||||||
120:47-120:53: @4[8]: _11 = &(*_12)
|
120:47-120:53: @4[8]: _11 = &(*_12)
|
||||||
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb19]
|
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb22]
|
||||||
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let mut context = Context::from_waker(&waker)<span class="annotation">⦉@0,1,2,3,4,5</span></span></span><span class="code" style="--layer: 0">;</span></span>
|
120:13-120:24: @5[1]: FakeRead(ForLet, _10)"> let mut context = Context::from_waker(&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"></span></span>
|
||||||
<span class="line"><span class="code" style="--layer: 0"> loop {</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: <F as std::future::Future>::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 = &mut _2
|
<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: <F as std::future::Future>::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 = &mut _2
|
||||||
123:39-123:54: @7.Call: _15 = Pin::<&mut F>::as_mut(move _16) -> [return: bb8, unwind: bb19]
|
123:39-123:54: @7.Call: _15 = Pin::<&mut F>::as_mut(move _16) -> [return: bb8, unwind: bb22]
|
||||||
123:60-123:72: @8[3]: _18 = &mut _10
|
123:60-123:72: @8[3]: _18 = &mut _10
|
||||||
123:60-123:72: @8[4]: _17 = &mut (*_18)
|
123:60-123:72: @8[4]: _17 = &mut (*_18)
|
||||||
123:39-123:73: @8.Call: _14 = <F as Future>::poll(move _15, move _17) -> [return: bb9, unwind: bb19]
|
123:39-123:73: @8.Call: _14 = <F as Future>::poll(move _15, move _17) -> [return: bb9, unwind: bb22]
|
||||||
123:39-123:73: @9[2]: FakeRead(ForMatchedPlace, _14)"><span class="annotation">@6,7,8,9⦊</span>future.as_mut().poll(&mut context)<span class="annotation">⦉@6,7,8,9</span></span></span><span class="code" style="--layer: 0"> {</span></span>
|
123:39-123:73: @9[2]: FakeRead(ForMatchedPlace, _14)"><span class="annotation">@6,7,8,9⦊</span>future.as_mut().poll(&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"> 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>
|
<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>
|
||||||
|
|
|
@ -69,9 +69,9 @@ For revisions in Pull Requests (PR):
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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) -> [return: bb1, unwind: bb16]
|
<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) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -82,9 +82,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
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>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -95,9 +95,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
93:11-101:2: @12[2]: _0 = const ()
|
||||||
101:2-101:2: @13.Return: return"> let _ = g(10);</span></span>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -108,9 +108,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
93:11-101:2: @12[2]: _0 = const ()
|
||||||
101:2-101:2: @13.Return: return"> let _ = h(9);</span></span>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -121,9 +121,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
93:11-101:2: @12[2]: _0 = const ()
|
||||||
101:2-101:2: @13.Return: return"> let mut future = Box::pin(i(8));</span></span>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -134,9 +134,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
93:11-101:2: @12[2]: _0 = const ()
|
||||||
101:2-101:2: @13.Return: return"> j(7);</span></span>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -147,9 +147,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
93:11-101:2: @12[2]: _0 = const ()
|
||||||
101:2-101:2: @13.Return: return"> l(6);</span></span>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -160,9 +160,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
93:11-101:2: @12[2]: _0 = const ()
|
||||||
101:2-101:2: @13.Return: return"> let _ = m(5);</span></span>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
@ -173,9 +173,9 @@ For revisions in Pull Requests (PR):
|
||||||
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
100:5-100:40: @11.Call: _8 = block_on::<Pin<&mut impl Future>>(move _9) -> [return: bb12, unwind: bb14]
|
||||||
93:11-101:2: @12[2]: _0 = const ()
|
93:11-101:2: @12[2]: _0 = const ()
|
||||||
101:2-101:2: @13.Return: return"> executor::block_on(future.as_mut());</span></span>
|
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) -> [return: bb1, unwind: bb16]
|
<span class="line"><span class="code even" style="--layer: 1" title="94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb15]
|
||||||
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb16]
|
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb15]
|
||||||
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb16]
|
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb15]
|
||||||
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
96:22-96:36: @5.Call: _3 = Box::<impl Future>::pin(move _4) -> [return: bb6, unwind: bb15]
|
||||||
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
96:9-96:19: @6[1]: FakeRead(ForLet, _3)
|
||||||
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
|
||||||
|
|
|
@ -97,13 +97,13 @@ For revisions in Pull Requests (PR):
|
||||||
103:9-103:29: @4[23]: _18 = (_16.0: &&str)
|
103:9-103:29: @4[23]: _18 = (_16.0: &&str)
|
||||||
103:9-103:29: @4[26]: _20 = &(*_18)
|
103:9-103:29: @4[26]: _20 = &(*_18)
|
||||||
103:9-103:29: @4[28]: _21 = <&str as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r &str, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
103:9-103:29: @4[28]: _21 = <&str as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r &str, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||||
103:9-103:29: @4.Call: _19 = ArgumentV1::new::<&str>(move _20, move _21) -> [return: bb5, unwind: bb9]
|
103:9-103:29: @4.Call: _19 = ArgumentV1::new::<&str>(move _20, move _21) -> [return: bb5, unwind: bb10]
|
||||||
103:9-103:29: @5[2]: _15 = [move _19]
|
103:9-103:29: @5[2]: _15 = [move _19]
|
||||||
103:9-103:29: @5[5]: _14 = &_15
|
103:9-103:29: @5[5]: _14 = &_15
|
||||||
103:9-103:29: @5[6]: _13 = &(*_14)
|
103:9-103:29: @5[6]: _13 = &(*_14)
|
||||||
103:9-103:29: @5[7]: _12 = move _13 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
103:9-103:29: @5[7]: _12 = move _13 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||||
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -> [return: bb6, unwind: bb9]
|
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -> [return: bb6, unwind: bb10]
|
||||||
103:9-103:29: @6.Call: _6 = format(move _7) -> [return: bb7, unwind: bb9]
|
103:9-103:29: @6.Call: _6 = format(move _7) -> [return: bb7, unwind: bb10]
|
||||||
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
|
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
|
||||||
103:9-103:29: @7[6]: _0 = move _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>
|
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: &&str)
|
103:9-103:29: @4[23]: _18 = (_16.0: &&str)
|
||||||
103:9-103:29: @4[26]: _20 = &(*_18)
|
103:9-103:29: @4[26]: _20 = &(*_18)
|
||||||
103:9-103:29: @4[28]: _21 = <&str as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r &str, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
103:9-103:29: @4[28]: _21 = <&str as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r &str, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||||
103:9-103:29: @4.Call: _19 = ArgumentV1::new::<&str>(move _20, move _21) -> [return: bb5, unwind: bb9]
|
103:9-103:29: @4.Call: _19 = ArgumentV1::new::<&str>(move _20, move _21) -> [return: bb5, unwind: bb10]
|
||||||
103:9-103:29: @5[2]: _15 = [move _19]
|
103:9-103:29: @5[2]: _15 = [move _19]
|
||||||
103:9-103:29: @5[5]: _14 = &_15
|
103:9-103:29: @5[5]: _14 = &_15
|
||||||
103:9-103:29: @5[6]: _13 = &(*_14)
|
103:9-103:29: @5[6]: _13 = &(*_14)
|
||||||
103:9-103:29: @5[7]: _12 = move _13 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
103:9-103:29: @5[7]: _12 = move _13 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||||
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -> [return: bb6, unwind: bb9]
|
103:9-103:29: @5.Call: _7 = Arguments::new_v1(move _8, move _12) -> [return: bb6, unwind: bb10]
|
||||||
103:9-103:29: @6.Call: _6 = format(move _7) -> [return: bb7, unwind: bb9]
|
103:9-103:29: @6.Call: _6 = format(move _7) -> [return: bb7, unwind: bb10]
|
||||||
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
|
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
|
||||||
103:9-103:29: @7[6]: _0 = move _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>
|
104:6-104:6: @8.Return: return"> }<span class="annotation">⦉@4,5,6,7,8</span></span></span></span></div>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -69,122 +69,122 @@ For revisions in Pull Requests (PR):
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[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>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[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>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[1]: _0 = const ()
|
||||||
61:2-61:2: @8.Return: return"> used_with_same_type_from_bin_crate_and_lib_crate_generic_function(</span></span>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[1]: _0 = const ()
|
||||||
61:2-61:2: @8.Return: return"> "used from library used_crate.rs",</span></span>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[1]: _0 = const ()
|
||||||
61:2-61:2: @8.Return: return"> );</span></span>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[1]: _0 = const ()
|
||||||
61:2-61:2: @8.Return: return"> let some_vec = vec![5, 6, 7, 8];</span></span>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[1]: _0 = const ()
|
||||||
61:2-61:2: @8.Return: return"> used_only_from_this_lib_crate_generic_function(some_vec);</span></span>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[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>
|
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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb13]
|
<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::<&str>(const "used from library used_crate.rs") -> [return: bb1, unwind: bb10]
|
||||||
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb13]
|
55:5-57:6: @1.Call: _2 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "used from library used_crate.rs") -> [return: bb2, unwind: bb10]
|
||||||
58:20-58:36: @2[5]: _6 = Box([i32; 4])
|
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[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[7]: _5 = move _6
|
||||||
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
58:20-58:36: @2[8]: _4 = move _5 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
58:20-58:36: @4.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb5, unwind: bb12]
|
58:20-58:36: @3.Call: _3 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _4) -> [return: bb4, unwind: bb10]
|
||||||
58:9-58:17: @5[1]: FakeRead(ForLet, _3)
|
58:9-58:17: @4[1]: FakeRead(ForLet, _3)
|
||||||
59:52-59:60: @5[4]: _8 = move _3
|
59:52-59:60: @4[4]: _8 = move _3
|
||||||
59:5-59:61: @5.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb6, unwind: bb9]
|
59:5-59:61: @4.Call: _7 = used_only_from_this_lib_crate_generic_function::<Vec<i32>>(move _8) -> [return: bb5, unwind: bb8]
|
||||||
60:5-60:91: @6.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb7, unwind: bb10]
|
60:5-60:91: @5.Call: _9 = used_only_from_this_lib_crate_generic_function::<&str>(const "used ONLY from library used_crate.rs") -> [return: bb6, unwind: bb8]
|
||||||
53:25-61:2: @7[1]: _0 = const ()
|
53:25-61:2: @6[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>
|
61:2-61:2: @7.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7</span></span></span></span></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -69,125 +69,125 @@ For revisions in Pull Requests (PR):
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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() -> [return: bb1, unwind: bb14]
|
<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() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[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>
|
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() -> [return: bb1, unwind: bb14]
|
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[1]: _0 = const ()
|
||||||
12:2-12:2: @9.Return: return"> used_crate::used_function();</span></span>
|
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() -> [return: bb1, unwind: bb14]
|
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[1]: _0 = const ()
|
||||||
12:2-12:2: @9.Return: return"> let some_vec = vec![1, 2, 3, 4];</span></span>
|
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() -> [return: bb1, unwind: bb14]
|
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[1]: _0 = const ()
|
||||||
12:2-12:2: @9.Return: return"> used_crate::used_only_from_bin_crate_generic_function(&some_vec);</span></span>
|
12:2-12:2: @8.Return: return"> used_crate::used_only_from_bin_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() -> [return: bb1, unwind: bb14]
|
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[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>
|
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() -> [return: bb1, unwind: bb14]
|
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[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>
|
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() -> [return: bb1, unwind: bb14]
|
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[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>
|
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() -> [return: bb1, unwind: bb14]
|
<span class="line"><span class="code even" style="--layer: 1" title="6:5-6:32: @0.Call: _1 = used_function() -> [return: bb1, unwind: bb11]
|
||||||
7:20-7:36: @1[5]: _5 = Box([i32; 4])
|
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[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[7]: _4 = move _5
|
||||||
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
7:20-7:36: @1[8]: _3 = move _4 as std::boxed::Box<[i32]> (Pointer(Unsize))
|
||||||
7:20-7:36: @3.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb4, unwind: bb13]
|
7:20-7:36: @2.Call: _2 = slice::<impl [i32]>::into_vec::<std::alloc::Global>(move _3) -> [return: bb3, unwind: bb11]
|
||||||
7:9-7:17: @4[1]: FakeRead(ForLet, _2)
|
7:9-7:17: @3[1]: FakeRead(ForLet, _2)
|
||||||
8:59-8:68: @4[4]: _7 = &_2
|
8:59-8:68: @3[4]: _7 = &_2
|
||||||
8:5-8:69: @4.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb5, unwind: bb11]
|
8:5-8:69: @3.Call: _6 = used_only_from_bin_crate_generic_function::<&Vec<i32>>(move _7) -> [return: bb4, unwind: bb9]
|
||||||
9:5-9:89: @5.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb6, unwind: bb11]
|
9:5-9:89: @4.Call: _8 = used_only_from_bin_crate_generic_function::<&str>(const "used from bin uses_crate.rs") -> [return: bb5, unwind: bb9]
|
||||||
10:68-10:76: @6[3]: _10 = move _2
|
10:68-10:76: @5[3]: _10 = move _2
|
||||||
10:5-10:77: @6.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb7, unwind: bb10]
|
10:5-10:77: @5.Call: _9 = used_from_bin_crate_and_lib_crate_generic_function::<Vec<i32>>(move _10) -> [return: bb6, unwind: bb9]
|
||||||
11:5-11:98: @7.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb8, unwind: bb11]
|
11:5-11:98: @6.Call: _11 = used_with_same_type_from_bin_crate_and_lib_crate_generic_function::<&str>(const "interesting?") -> [return: bb7, unwind: bb9]
|
||||||
5:11-12:2: @8[1]: _0 = const ()
|
5:11-12:2: @7[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>
|
12:2-12:2: @8.Return: return">}<span class="annotation">⦉@0,1,2,3,4,5,6,7,8</span></span></span></span></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -43,6 +43,7 @@ impl<T: Unpin> Future for Defer<T> {
|
||||||
/// The `failing_op`-th operation will panic.
|
/// The `failing_op`-th operation will panic.
|
||||||
struct Allocator {
|
struct Allocator {
|
||||||
data: RefCell<Vec<bool>>,
|
data: RefCell<Vec<bool>>,
|
||||||
|
name: &'static str,
|
||||||
failing_op: usize,
|
failing_op: usize,
|
||||||
cur_ops: Cell<usize>,
|
cur_ops: Cell<usize>,
|
||||||
}
|
}
|
||||||
|
@ -54,23 +55,28 @@ impl Drop for Allocator {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let data = self.data.borrow();
|
let data = self.data.borrow();
|
||||||
if data.iter().any(|d| *d) {
|
if data.iter().any(|d| *d) {
|
||||||
panic!("missing free: {:?}", data);
|
panic!("missing free in {:?}: {:?}", self.name, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Allocator {
|
impl Allocator {
|
||||||
fn new(failing_op: usize) -> Self {
|
fn new(failing_op: usize, name: &'static str) -> Self {
|
||||||
Allocator { failing_op, cur_ops: Cell::new(0), data: RefCell::new(vec![]) }
|
Allocator {
|
||||||
|
failing_op,
|
||||||
|
name,
|
||||||
|
cur_ops: Cell::new(0),
|
||||||
|
data: RefCell::new(vec![]),
|
||||||
}
|
}
|
||||||
fn alloc(&self) -> impl Future<Output = Ptr<'_>> + '_ {
|
}
|
||||||
|
fn alloc(self: &Rc<Allocator>) -> impl Future<Output = Ptr> + 'static {
|
||||||
self.fallible_operation();
|
self.fallible_operation();
|
||||||
|
|
||||||
let mut data = self.data.borrow_mut();
|
let mut data = self.data.borrow_mut();
|
||||||
|
|
||||||
let addr = data.len();
|
let addr = data.len();
|
||||||
data.push(true);
|
data.push(true);
|
||||||
Defer { ready: false, value: Some(Ptr(addr, self)) }
|
Defer { ready: false, value: Some(Ptr(addr, self.clone())) }
|
||||||
}
|
}
|
||||||
fn fallible_operation(&self) {
|
fn fallible_operation(&self) {
|
||||||
self.cur_ops.set(self.cur_ops.get() + 1);
|
self.cur_ops.set(self.cur_ops.get() + 1);
|
||||||
|
@ -83,11 +89,11 @@ impl Allocator {
|
||||||
|
|
||||||
// Type that tracks whether it was dropped and can panic when it's created or
|
// Type that tracks whether it was dropped and can panic when it's created or
|
||||||
// destroyed.
|
// destroyed.
|
||||||
struct Ptr<'a>(usize, &'a Allocator);
|
struct Ptr(usize, Rc<Allocator>);
|
||||||
impl<'a> Drop for Ptr<'a> {
|
impl Drop for Ptr {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
match self.1.data.borrow_mut()[self.0] {
|
match self.1.data.borrow_mut()[self.0] {
|
||||||
false => panic!("double free at index {:?}", self.0),
|
false => panic!("double free in {:?} at index {:?}", self.1.name, self.0),
|
||||||
ref mut d => *d = false,
|
ref mut d => *d = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +117,7 @@ async fn dynamic_drop(a: Rc<Allocator>, c: bool) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>);
|
struct TwoPtrs(Ptr, Ptr);
|
||||||
async fn struct_dynamic_drop(a: Rc<Allocator>, c0: bool, c1: bool, c: bool) {
|
async fn struct_dynamic_drop(a: Rc<Allocator>, c0: bool, c1: bool, c: bool) {
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
let x;
|
let x;
|
||||||
|
@ -232,21 +238,62 @@ async fn move_ref_pattern(a: Rc<Allocator>) {
|
||||||
a.alloc().await;
|
a.alloc().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_test<F, G>(cx: &mut Context<'_>, ref f: F)
|
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)
|
||||||
where
|
where
|
||||||
F: Fn(Rc<Allocator>) -> G,
|
F: Fn(Rc<Allocator>) -> G,
|
||||||
G: Future<Output = ()>,
|
G: Future<Output = O>,
|
||||||
{
|
{
|
||||||
for polls in 0.. {
|
for polls in 0.. {
|
||||||
// Run without any panics to find which operations happen after the
|
// Run without any panics to find which operations happen after the
|
||||||
// penultimate `poll`.
|
// penultimate `poll`.
|
||||||
let first_alloc = Rc::new(Allocator::new(usize::MAX));
|
let first_alloc = Rc::new(Allocator::new(usize::MAX, name));
|
||||||
let mut fut = Box::pin(f(first_alloc.clone()));
|
let mut fut = Box::pin(f(first_alloc.clone()));
|
||||||
let mut ops_before_last_poll = 0;
|
let mut ops_before_last_poll = 0;
|
||||||
let mut completed = false;
|
let mut completed = false;
|
||||||
for _ in 0..polls {
|
for _ in 0..polls {
|
||||||
ops_before_last_poll = first_alloc.cur_ops.get();
|
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;
|
completed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,7 +302,7 @@ where
|
||||||
// Start at `ops_before_last_poll` so that we will always be able to
|
// Start at `ops_before_last_poll` so that we will always be able to
|
||||||
// `poll` the expected number of times.
|
// `poll` the expected number of times.
|
||||||
for failing_op in ops_before_last_poll..first_alloc.cur_ops.get() {
|
for failing_op in ops_before_last_poll..first_alloc.cur_ops.get() {
|
||||||
let alloc = Rc::new(Allocator::new(failing_op + 1));
|
let alloc = Rc::new(Allocator::new(failing_op + 1, name));
|
||||||
let f = &f;
|
let f = &f;
|
||||||
let cx = &mut *cx;
|
let cx = &mut *cx;
|
||||||
let result = panic::catch_unwind(panic::AssertUnwindSafe(move || {
|
let result = panic::catch_unwind(panic::AssertUnwindSafe(move || {
|
||||||
|
@ -285,48 +332,58 @@ fn clone_waker(data: *const ()) -> RawWaker {
|
||||||
RawWaker::new(data, &RawWakerVTable::new(clone_waker, drop, drop, drop))
|
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() {
|
fn main() {
|
||||||
let waker = unsafe { Waker::from_raw(clone_waker(ptr::null())) };
|
let waker = unsafe { Waker::from_raw(clone_waker(ptr::null())) };
|
||||||
let context = &mut Context::from_waker(&waker);
|
let context = &mut Context::from_waker(&waker);
|
||||||
|
|
||||||
run_test(context, |a| dynamic_init(a, false));
|
run_test!(context, |a| dynamic_init(a, false));
|
||||||
run_test(context, |a| dynamic_init(a, true));
|
run_test!(context, |a| dynamic_init(a, true));
|
||||||
run_test(context, |a| dynamic_drop(a, false));
|
run_test!(context, |a| dynamic_drop(a, false));
|
||||||
run_test(context, |a| dynamic_drop(a, true));
|
run_test!(context, |a| dynamic_drop(a, true));
|
||||||
|
|
||||||
run_test(context, |a| assignment(a, false, false));
|
run_test!(context, |a| assignment(a, false, false));
|
||||||
run_test(context, |a| assignment(a, false, true));
|
run_test!(context, |a| assignment(a, false, true));
|
||||||
run_test(context, |a| assignment(a, true, false));
|
run_test!(context, |a| assignment(a, true, false));
|
||||||
run_test(context, |a| assignment(a, true, true));
|
run_test!(context, |a| assignment(a, true, true));
|
||||||
|
|
||||||
run_test(context, |a| array_simple(a));
|
run_test!(context, |a| array_simple(a));
|
||||||
run_test(context, |a| vec_simple(a));
|
run_test!(context, |a| vec_simple(a));
|
||||||
run_test(context, |a| vec_unreachable(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, false));
|
||||||
run_test(context, |a| struct_dynamic_drop(a, false, false, true));
|
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, false));
|
||||||
run_test(context, |a| struct_dynamic_drop(a, false, true, true));
|
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, false));
|
||||||
run_test(context, |a| struct_dynamic_drop(a, true, false, true));
|
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, false));
|
||||||
run_test(context, |a| struct_dynamic_drop(a, true, true, true));
|
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, false));
|
||||||
run_test(context, |a| field_assignment(a, true));
|
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, 0));
|
||||||
run_test(context, |a| slice_pattern_one_of(a, 1));
|
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, 2));
|
||||||
run_test(context, |a| slice_pattern_one_of(a, 3));
|
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, 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, 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, true));
|
||||||
run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
|
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_reassign(a));
|
||||||
|
|
||||||
run_test(context, |a| move_ref_pattern(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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#![feature(generators, generator_trait)]
|
#![feature(generators, generator_trait)]
|
||||||
#![feature(bindings_after_at)]
|
#![feature(bindings_after_at)]
|
||||||
|
|
||||||
#![allow(unused_assignments)]
|
#![allow(unused_assignments)]
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
|
@ -17,6 +16,7 @@ struct InjectedFailure;
|
||||||
|
|
||||||
struct Allocator {
|
struct Allocator {
|
||||||
data: RefCell<Vec<bool>>,
|
data: RefCell<Vec<bool>>,
|
||||||
|
name: &'static str,
|
||||||
failing_op: usize,
|
failing_op: usize,
|
||||||
cur_ops: Cell<usize>,
|
cur_ops: Cell<usize>,
|
||||||
}
|
}
|
||||||
|
@ -28,17 +28,18 @@ impl Drop for Allocator {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let data = self.data.borrow();
|
let data = self.data.borrow();
|
||||||
if data.iter().any(|d| *d) {
|
if data.iter().any(|d| *d) {
|
||||||
panic!("missing free: {:?}", data);
|
panic!("missing free in {:?}: {:?}", self.name, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Allocator {
|
impl Allocator {
|
||||||
fn new(failing_op: usize) -> Self {
|
fn new(failing_op: usize, name: &'static str) -> Self {
|
||||||
Allocator {
|
Allocator {
|
||||||
failing_op: failing_op,
|
failing_op: failing_op,
|
||||||
cur_ops: Cell::new(0),
|
cur_ops: Cell::new(0),
|
||||||
data: RefCell::new(vec![])
|
data: RefCell::new(vec![]),
|
||||||
|
name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn alloc(&self) -> Ptr<'_> {
|
fn alloc(&self) -> Ptr<'_> {
|
||||||
|
@ -53,33 +54,17 @@ impl Allocator {
|
||||||
data.push(true);
|
data.push(true);
|
||||||
Ptr(addr, self)
|
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);
|
struct Ptr<'a>(usize, &'a Allocator);
|
||||||
impl<'a> Drop for Ptr<'a> {
|
impl<'a> Drop for Ptr<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
match self.1.data.borrow_mut()[self.0] {
|
match self.1.data.borrow_mut()[self.0] {
|
||||||
false => {
|
false => panic!("double free in {:?} at index {:?}", self.1.name, self.0),
|
||||||
panic!("double free at index {:?}", self.0)
|
ref mut d => *d = false,
|
||||||
}
|
|
||||||
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 {
|
if self.1.cur_ops.get() == self.1.failing_op {
|
||||||
panic!(InjectedFailure);
|
panic!(InjectedFailure);
|
||||||
|
@ -177,11 +162,7 @@ fn generator(a: &Allocator, run_count: usize) {
|
||||||
assert!(run_count < 4);
|
assert!(run_count < 4);
|
||||||
|
|
||||||
let mut gen = || {
|
let mut gen = || {
|
||||||
(a.alloc(),
|
(a.alloc(), yield a.alloc(), a.alloc(), yield a.alloc());
|
||||||
yield a.alloc(),
|
|
||||||
a.alloc(),
|
|
||||||
yield a.alloc()
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
for _ in 0..run_count {
|
for _ in 0..run_count {
|
||||||
Pin::new(&mut gen).resume(());
|
Pin::new(&mut gen).resume(());
|
||||||
|
@ -205,28 +186,40 @@ fn vec_unreachable(a: &Allocator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slice_pattern_first(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) {
|
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) {
|
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) {
|
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) {
|
fn slice_pattern_one_of(a: &Allocator, i: usize) {
|
||||||
let array = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
|
let array = [a.alloc(), a.alloc(), a.alloc(), a.alloc()];
|
||||||
let _x = match i {
|
let _x = match i {
|
||||||
0 => { let [a, ..] = array; a }
|
0 => {
|
||||||
1 => { let [_, a, ..] = array; a }
|
let [a, ..] = array;
|
||||||
2 => { let [_, _, a, _] = array; a }
|
a
|
||||||
3 => { let [_, _, _, a] = array; a }
|
}
|
||||||
|
1 => {
|
||||||
|
let [_, a, ..] = array;
|
||||||
|
a
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
let [_, _, a, _] = array;
|
||||||
|
a
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
let [_, _, _, a] = array;
|
||||||
|
a
|
||||||
|
}
|
||||||
_ => panic!("unmatched"),
|
_ => panic!("unmatched"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -234,9 +227,9 @@ fn slice_pattern_one_of(a: &Allocator, i: usize) {
|
||||||
fn subslice_pattern_from_end(a: &Allocator, arg: bool) {
|
fn subslice_pattern_from_end(a: &Allocator, arg: bool) {
|
||||||
let a = [a.alloc(), a.alloc(), a.alloc()];
|
let a = [a.alloc(), a.alloc(), a.alloc()];
|
||||||
if arg {
|
if arg {
|
||||||
let[.., _x, _] = a;
|
let [.., _x, _] = a;
|
||||||
} else {
|
} else {
|
||||||
let[_, _y @ ..] = a;
|
let [_, _y @ ..] = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,45 +241,61 @@ fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if arg {
|
if arg {
|
||||||
let[.., _x, _] = a;
|
let [.., _x, _] = a;
|
||||||
} else {
|
} else {
|
||||||
let[_, _y @ ..] = a;
|
let [_, _y @ ..] = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slice_pattern_reassign(a: &Allocator) {
|
fn slice_pattern_reassign(a: &Allocator) {
|
||||||
let mut ar = [a.alloc(), a.alloc()];
|
let mut ar = [a.alloc(), a.alloc()];
|
||||||
let[_, _x] = ar;
|
let [_, _x] = ar;
|
||||||
ar = [a.alloc(), a.alloc()];
|
ar = [a.alloc(), a.alloc()];
|
||||||
let[.., _y] = ar;
|
let [.., _y] = ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subslice_pattern_reassign(a: &Allocator) {
|
fn subslice_pattern_reassign(a: &Allocator) {
|
||||||
let mut ar = [a.alloc(), a.alloc(), a.alloc()];
|
let mut ar = [a.alloc(), a.alloc(), a.alloc()];
|
||||||
let[_, _, _x] = ar;
|
let [_, _, _x] = ar;
|
||||||
ar = [a.alloc(), a.alloc(), a.alloc()];
|
ar = [a.alloc(), a.alloc(), a.alloc()];
|
||||||
let[_, _y @ ..] = ar;
|
let [_, _y @ ..] = ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index_field_mixed_ends(a: &Allocator) {
|
fn index_field_mixed_ends(a: &Allocator) {
|
||||||
let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
|
let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
|
||||||
let[(_x, _), ..] = ar;
|
let [(_x, _), ..] = ar;
|
||||||
let[(_, _y), _] = ar;
|
let [(_, _y), _] = ar;
|
||||||
let[_, (_, _w)] = ar;
|
let [_, (_, _w)] = ar;
|
||||||
let[.., (_z, _)] = ar;
|
let [.., (_z, _)] = ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subslice_mixed_min_lengths(a: &Allocator, c: i32) {
|
fn subslice_mixed_min_lengths(a: &Allocator, c: i32) {
|
||||||
let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
|
let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())];
|
||||||
match c {
|
match c {
|
||||||
0 => { let[_x, ..] = ar; }
|
0 => {
|
||||||
1 => { let[_x, _, ..] = ar; }
|
let [_x, ..] = ar;
|
||||||
2 => { let[_x, _] = ar; }
|
}
|
||||||
3 => { let[(_x, _), _, ..] = ar; }
|
1 => {
|
||||||
4 => { let[.., (_x, _)] = ar; }
|
let [_x, _, ..] = ar;
|
||||||
5 => { let[.., (_x, _), _] = ar; }
|
}
|
||||||
6 => { let [_y @ ..] = ar; }
|
2 => {
|
||||||
_ => { let [_y @ .., _] = ar; }
|
let [_x, _] = ar;
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
let [(_x, _), _, ..] = ar;
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
let [.., (_x, _)] = ar;
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
let [.., (_x, _), _] = ar;
|
||||||
|
}
|
||||||
|
6 => {
|
||||||
|
let [_y @ ..] = ar;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let [_y @ .., _] = ar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,87 +343,160 @@ fn move_ref_pattern(a: &Allocator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn panic_after_return(a: &Allocator) -> Ptr<'_> {
|
fn panic_after_return(a: &Allocator) -> Ptr<'_> {
|
||||||
// Panic in the drop of `p` or `q` can leak
|
|
||||||
let exceptions = vec![8, 9];
|
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let p = a.alloc();
|
let p = a.alloc();
|
||||||
{
|
{
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let p = a.alloc();
|
let p = a.alloc();
|
||||||
// FIXME (#47949) We leak values when we panic in a destructor after
|
a.alloc()
|
||||||
// evaluating an expression with `rustc_mir::build::Builder::into`.
|
|
||||||
a.alloc_leaked(exceptions)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn panic_after_return_expr(a: &Allocator) -> Ptr<'_> {
|
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();
|
a.alloc();
|
||||||
let p = a.alloc();
|
let p = a.alloc();
|
||||||
{
|
{
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let q = a.alloc();
|
let q = a.alloc();
|
||||||
// FIXME (#47949)
|
return a.alloc();
|
||||||
return a.alloc_leaked(exceptions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn panic_after_init(a: &Allocator) {
|
fn panic_after_init(a: &Allocator) {
|
||||||
// Panic in the drop of `r` can leak
|
|
||||||
let exceptions = vec![8];
|
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let p = a.alloc();
|
let p = a.alloc();
|
||||||
let q = {
|
let q = {
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let r = a.alloc();
|
let r = a.alloc();
|
||||||
// FIXME (#47949)
|
a.alloc()
|
||||||
a.alloc_leaked(exceptions)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn panic_after_init_temp(a: &Allocator) {
|
fn panic_after_init_temp(a: &Allocator) {
|
||||||
// Panic in the drop of `r` can leak
|
|
||||||
let exceptions = vec![8];
|
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let p = a.alloc();
|
let p = a.alloc();
|
||||||
{
|
{
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let r = a.alloc();
|
let r = a.alloc();
|
||||||
// FIXME (#47949)
|
a.alloc()
|
||||||
a.alloc_leaked(exceptions)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn panic_after_init_by_loop(a: &Allocator) {
|
fn panic_after_init_by_loop(a: &Allocator) {
|
||||||
// Panic in the drop of `r` can leak
|
|
||||||
let exceptions = vec![8];
|
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let p = a.alloc();
|
let p = a.alloc();
|
||||||
let q = loop {
|
let q = loop {
|
||||||
a.alloc();
|
a.alloc();
|
||||||
let r = a.alloc();
|
let r = a.alloc();
|
||||||
// FIXME (#47949)
|
break a.alloc();
|
||||||
break a.alloc_leaked(exceptions);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_test<F>(mut f: F)
|
fn panic_after_init_by_match(a: &Allocator, b: bool) {
|
||||||
where F: FnMut(&Allocator)
|
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),
|
||||||
{
|
{
|
||||||
let first_alloc = Allocator::new(usize::MAX);
|
let first_alloc = Allocator::new(usize::MAX, name);
|
||||||
f(&first_alloc);
|
f(&first_alloc);
|
||||||
|
|
||||||
for failing_op in 1..first_alloc.cur_ops.get()+1 {
|
for failing_op in 1..first_alloc.cur_ops.get() + 1 {
|
||||||
let alloc = Allocator::new(failing_op);
|
let alloc = Allocator::new(failing_op, name);
|
||||||
let alloc = &alloc;
|
let alloc = &alloc;
|
||||||
let f = panic::AssertUnwindSafe(&mut f);
|
let f = panic::AssertUnwindSafe(&mut f);
|
||||||
let result = panic::catch_unwind(move || {
|
let result = panic::catch_unwind(move || {
|
||||||
f.0(alloc);
|
f.0(alloc);
|
||||||
});
|
});
|
||||||
match result {
|
match result {
|
||||||
Ok(..) => panic!("test executed {} ops but now {}",
|
Ok(..) => panic!(
|
||||||
first_alloc.cur_ops.get(), alloc.cur_ops.get()),
|
"test executed {} ops but now {}",
|
||||||
|
first_alloc.cur_ops.get(),
|
||||||
|
alloc.cur_ops.get()
|
||||||
|
),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.downcast_ref::<InjectedFailure>().is_none() {
|
if e.downcast_ref::<InjectedFailure>().is_none() {
|
||||||
panic::resume_unwind(e);
|
panic::resume_unwind(e);
|
||||||
|
@ -424,98 +506,115 @@ fn run_test<F>(mut f: F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_test_nopanic<F>(mut f: F)
|
fn run_test_nopanic<F>(mut f: F, name: &'static str)
|
||||||
where F: FnMut(&Allocator)
|
where
|
||||||
|
F: FnMut(&Allocator),
|
||||||
{
|
{
|
||||||
let first_alloc = Allocator::new(usize::MAX);
|
let first_alloc = Allocator::new(usize::MAX, name);
|
||||||
f(&first_alloc);
|
f(&first_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! run_test {
|
||||||
|
($e:expr) => {
|
||||||
|
run_test($e, stringify!($e));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
run_test(|a| dynamic_init(a, false));
|
run_test!(|a| dynamic_init(a, false));
|
||||||
run_test(|a| dynamic_init(a, true));
|
run_test!(|a| dynamic_init(a, true));
|
||||||
run_test(|a| dynamic_drop(a, false));
|
run_test!(|a| dynamic_drop(a, false));
|
||||||
run_test(|a| dynamic_drop(a, true));
|
run_test!(|a| dynamic_drop(a, true));
|
||||||
|
|
||||||
run_test(|a| assignment2(a, false, false));
|
run_test!(|a| assignment2(a, false, false));
|
||||||
run_test(|a| assignment2(a, false, true));
|
run_test!(|a| assignment2(a, false, true));
|
||||||
run_test(|a| assignment2(a, true, false));
|
run_test!(|a| assignment2(a, true, false));
|
||||||
run_test(|a| assignment2(a, true, true));
|
run_test!(|a| assignment2(a, true, true));
|
||||||
|
|
||||||
run_test(|a| assignment1(a, false));
|
run_test!(|a| assignment1(a, false));
|
||||||
run_test(|a| assignment1(a, true));
|
run_test!(|a| assignment1(a, true));
|
||||||
|
|
||||||
run_test(|a| array_simple(a));
|
run_test!(|a| array_simple(a));
|
||||||
run_test(|a| vec_simple(a));
|
run_test!(|a| vec_simple(a));
|
||||||
run_test(|a| vec_unreachable(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, false));
|
||||||
run_test(|a| struct_dynamic_drop(a, false, false, true));
|
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, false));
|
||||||
run_test(|a| struct_dynamic_drop(a, false, true, true));
|
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, false));
|
||||||
run_test(|a| struct_dynamic_drop(a, true, false, true));
|
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, false));
|
||||||
run_test(|a| struct_dynamic_drop(a, true, true, true));
|
run_test!(|a| struct_dynamic_drop(a, true, true, true));
|
||||||
|
|
||||||
run_test(|a| field_assignment(a, false));
|
run_test!(|a| field_assignment(a, false));
|
||||||
run_test(|a| field_assignment(a, true));
|
run_test!(|a| field_assignment(a, true));
|
||||||
|
|
||||||
run_test(|a| generator(a, 0));
|
run_test!(|a| generator(a, 0));
|
||||||
run_test(|a| generator(a, 1));
|
run_test!(|a| generator(a, 1));
|
||||||
run_test(|a| generator(a, 2));
|
run_test!(|a| generator(a, 2));
|
||||||
run_test(|a| generator(a, 3));
|
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_first(a));
|
||||||
run_test(|a| slice_pattern_middle(a));
|
run_test!(|a| slice_pattern_middle(a));
|
||||||
run_test(|a| slice_pattern_two(a));
|
run_test!(|a| slice_pattern_two(a));
|
||||||
run_test(|a| slice_pattern_last(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, 0));
|
||||||
run_test(|a| slice_pattern_one_of(a, 1));
|
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, 2));
|
||||||
run_test(|a| slice_pattern_one_of(a, 3));
|
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, true));
|
||||||
run_test(|a| subslice_pattern_from_end(a, false));
|
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, true));
|
||||||
run_test(|a| subslice_pattern_from_end_with_drop(a, true, false));
|
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, true));
|
||||||
run_test(|a| subslice_pattern_from_end_with_drop(a, false, false));
|
run_test!(|a| subslice_pattern_from_end_with_drop(a, false, false));
|
||||||
run_test(|a| slice_pattern_reassign(a));
|
run_test!(|a| slice_pattern_reassign(a));
|
||||||
run_test(|a| subslice_pattern_reassign(a));
|
run_test!(|a| subslice_pattern_reassign(a));
|
||||||
|
|
||||||
run_test(|a| index_field_mixed_ends(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, 0));
|
||||||
run_test(|a| subslice_mixed_min_lengths(a, 1));
|
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, 2));
|
||||||
run_test(|a| subslice_mixed_min_lengths(a, 3));
|
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, 4));
|
||||||
run_test(|a| subslice_mixed_min_lengths(a, 5));
|
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, 6));
|
||||||
run_test(|a| subslice_mixed_min_lengths(a, 7));
|
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);
|
panic_after_return(a);
|
||||||
});
|
});
|
||||||
run_test(|a| {
|
run_test!(|a| {
|
||||||
panic_after_return_expr(a);
|
panic_after_return_expr(a);
|
||||||
});
|
});
|
||||||
run_test(|a| panic_after_init(a));
|
run_test!(|a| panic_after_init(a));
|
||||||
run_test(|a| panic_after_init_temp(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_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| bindings_after_at_dynamic_init_move(a, true));
|
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_move(a, false));
|
||||||
run_test(|a| bindings_after_at_dynamic_init_ref(a, true));
|
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_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, true));
|
||||||
run_test(|a| bindings_after_at_dynamic_drop_move(a, false));
|
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, true));
|
||||||
run_test(|a| bindings_after_at_dynamic_drop_ref(a, false));
|
run_test!(|a| bindings_after_at_dynamic_drop_ref(a, false));
|
||||||
|
|
||||||
run_test_nopanic(|a| union1(a));
|
run_test_nopanic(|a| union1(a), "|a| union1(a)");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue