Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a71a8194
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a71a8194
编写于
1月 21, 2021
作者:
F
Felix S. Klock II
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Revert "Avoid leaking block expression values"
This reverts commit
4fef3911
.
上级
dab3a80f
变更
20
展开全部
隐藏空白更改
内联
并排
Showing
20 changed file
with
10733 addition
and
10930 deletion
+10733
-10930
compiler/rustc_mir_build/src/build/block.rs
compiler/rustc_mir_build/src/build/block.rs
+3
-7
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+3
-8
compiler/rustc_mir_build/src/build/expr/as_temp.rs
compiler/rustc_mir_build/src/build/expr/as_temp.rs
+5
-1
compiler/rustc_mir_build/src/build/expr/into.rs
compiler/rustc_mir_build/src/build/expr/into.rs
+27
-59
compiler/rustc_mir_build/src/build/into.rs
compiler/rustc_mir_build/src/build/into.rs
+3
-8
compiler/rustc_mir_build/src/build/matches/mod.rs
compiler/rustc_mir_build/src/build/matches/mod.rs
+83
-15
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_mir_build/src/build/mod.rs
+10
-24
compiler/rustc_mir_build/src/build/scope.rs
compiler/rustc_mir_build/src/build/scope.rs
+16
-162
library/alloc/src/collections/btree/map/tests.rs
library/alloc/src/collections/btree/map/tests.rs
+1
-1
src/test/mir-opt/inline/inline_diverging.h.Inline.diff
src/test/mir-opt/inline/inline_diverging.h.Inline.diff
+5
-6
src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
+5
-9
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
...ps/coverage-reports/expected_show_coverage.uses_crate.txt
+2
-2
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html
...async.executor-block_on.-------.InstrumentCoverage.0.html
+57
-57
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html
...r_dump.async/async.main.-------.InstrumentCoverage.0.html
+27
-27
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html
...losure.main-{closure#2}.-------.InstrumentCoverage.0.html
+98
-0
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html
...mp.closure/closure.main.-------.InstrumentCoverage.0.html
+9996
-9996
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html
...rate.use_this_lib_crate.-------.InstrumentCoverage.0.html
+81
-81
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html
...s_crate/uses_crate.main.-------.InstrumentCoverage.0.html
+88
-88
src/test/ui/drop/dynamic-drop-async.rs
src/test/ui/drop/dynamic-drop-async.rs
+54
-111
src/test/ui/drop/dynamic-drop.rs
src/test/ui/drop/dynamic-drop.rs
+169
-268
未找到文件。
compiler/rustc_mir_build/src/build/block.rs
浏览文件 @
a71a8194
...
...
@@ -3,7 +3,6 @@
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
BlockFrame
,
Builder
};
use
crate
::
thir
::
*
;
use
rustc_hir
as
hir
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
use
rustc_session
::
lint
::
builtin
::
UNSAFE_OP_IN_UNSAFE_FN
;
use
rustc_session
::
lint
::
Level
;
...
...
@@ -13,7 +12,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
crate
fn
ast_block
(
&
mut
self
,
destination
:
Place
<
'tcx
>
,
scope
:
Option
<
region
::
Scope
>
,
block
:
BasicBlock
,
ast_block
:
&
'tcx
hir
::
Block
<
'tcx
>
,
source_info
:
SourceInfo
,
...
...
@@ -30,10 +28,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self
.in_opt_scope
(
opt_destruction_scope
.map
(|
de
|
(
de
,
source_info
)),
move
|
this
|
{
this
.in_scope
((
region_scope
,
source_info
),
LintLevel
::
Inherited
,
move
|
this
|
{
if
targeted_by_break
{
this
.in_breakable_scope
(
None
,
destination
,
s
cope
,
s
pan
,
|
this
|
{
this
.in_breakable_scope
(
None
,
destination
,
span
,
|
this
|
{
Some
(
this
.ast_block_stmts
(
destination
,
scope
,
block
,
span
,
stmts
,
...
...
@@ -42,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
))
})
}
else
{
this
.ast_block_stmts
(
destination
,
scope
,
block
,
span
,
stmts
,
expr
,
safety_mode
)
this
.ast_block_stmts
(
destination
,
block
,
span
,
stmts
,
expr
,
safety_mode
)
}
})
})
...
...
@@ -51,7 +48,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn
ast_block_stmts
(
&
mut
self
,
destination
:
Place
<
'tcx
>
,
scope
:
Option
<
region
::
Scope
>
,
mut
block
:
BasicBlock
,
span
:
Span
,
stmts
:
Vec
<
StmtRef
<
'tcx
>>
,
...
...
@@ -186,7 +182,7 @@ fn ast_block_stmts(
};
this
.block_context
.push
(
BlockFrame
::
TailExpr
{
tail_result_is_ignored
,
span
});
unpack!
(
block
=
this
.into
(
destination
,
scope
,
block
,
expr
));
unpack!
(
block
=
this
.into
(
destination
,
block
,
expr
));
let
popped
=
this
.block_context
.pop
();
assert
!
(
popped
.map_or
(
false
,
|
bf
|
bf
.is_tail_expr
()));
...
...
compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
浏览文件 @
a71a8194
...
...
@@ -115,15 +115,10 @@ fn expr_as_rvalue(
let
box_
=
Rvalue
::
NullaryOp
(
NullOp
::
Box
,
value
.ty
);
this
.cfg
.push_assign
(
block
,
source_info
,
Place
::
from
(
result
),
box_
);
// Initialize the box contents. No scope is needed since the
// `Box` is already scheduled to be dropped.
// initialize the box contents:
unpack!
(
block
=
this
.into
(
this
.hir
.tcx
()
.mk_place_deref
(
Place
::
from
(
result
)),
None
,
block
,
value
,
)
block
=
this
.into
(
this
.hir
.tcx
()
.mk_place_deref
(
Place
::
from
(
result
)),
block
,
value
)
);
let
result_operand
=
Operand
::
Move
(
Place
::
from
(
result
));
this
.record_operands_moved
(
slice
::
from_ref
(
&
result_operand
));
...
...
compiler/rustc_mir_build/src/build/expr/as_temp.rs
浏览文件 @
a71a8194
...
...
@@ -114,7 +114,11 @@ fn expr_as_temp(
}
}
unpack!
(
block
=
this
.into
(
temp_place
,
temp_lifetime
,
block
,
expr
));
unpack!
(
block
=
this
.into
(
temp_place
,
block
,
expr
));
if
let
Some
(
temp_lifetime
)
=
temp_lifetime
{
this
.schedule_drop
(
expr_span
,
temp_lifetime
,
temp
,
DropKind
::
Value
);
}
block
.and
(
temp
)
}
...
...
compiler/rustc_mir_build/src/build/expr/into.rs
浏览文件 @
a71a8194
//! See docs in build/expr/mod.rs
use
crate
::
build
::
expr
::
category
::{
Category
,
RvalueFunc
};
use
crate
::
build
::
scope
::
DropKind
;
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
BlockFrame
,
Builder
};
use
crate
::
thir
::
*
;
use
rustc_ast
::
InlineAsmOptions
;
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_data_structures
::
stack
::
ensure_sufficient_stack
;
use
rustc_hir
as
hir
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
ty
::
CanonicalUserTypeAnnotation
;
...
...
@@ -17,19 +15,13 @@
impl
<
'a
,
'tcx
>
Builder
<
'a
,
'tcx
>
{
/// Compile `expr`, storing the result into `destination`, which
/// is assumed to be uninitialized.
/// If a `drop_scope` is provided, `destination` is scheduled to be dropped
/// in `scope` once it has been initialized.
crate
fn
into_expr
(
&
mut
self
,
destination
:
Place
<
'tcx
>
,
scope
:
Option
<
region
::
Scope
>
,
mut
block
:
BasicBlock
,
expr
:
Expr
<
'tcx
>
,
)
->
BlockAnd
<
()
>
{
debug!
(
"into_expr(destination={:?}, scope={:?}, block={:?}, expr={:?})"
,
destination
,
scope
,
block
,
expr
);
debug!
(
"into_expr(destination={:?}, block={:?}, expr={:?})"
,
destination
,
block
,
expr
);
// since we frequently have to reference `self` from within a
// closure, where `self` would be shadowed, it's easier to
...
...
@@ -41,14 +33,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let
expr_is_block_or_scope
=
matches!
(
expr
.kind
,
ExprKind
::
Block
{
..
}
|
ExprKind
::
Scope
{
..
});
let
schedule_drop
=
move
|
this
:
&
mut
Self
|
{
if
let
Some
(
drop_scope
)
=
scope
{
let
local
=
destination
.as_local
()
.expect
(
"cannot schedule drop of non-Local place"
);
this
.schedule_drop
(
expr_span
,
drop_scope
,
local
,
DropKind
::
Value
);
}
};
if
!
expr_is_block_or_scope
{
this
.block_context
.push
(
BlockFrame
::
SubExpr
);
}
...
...
@@ -58,15 +42,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let
region_scope
=
(
region_scope
,
source_info
);
ensure_sufficient_stack
(||
{
this
.in_scope
(
region_scope
,
lint_level
,
|
this
|
{
this
.into
(
destination
,
scope
,
block
,
value
)
this
.into
(
destination
,
block
,
value
)
})
})
}
ExprKind
::
Block
{
body
:
ast_block
}
=>
{
this
.ast_block
(
destination
,
scope
,
block
,
ast_block
,
source_info
)
this
.ast_block
(
destination
,
block
,
ast_block
,
source_info
)
}
ExprKind
::
Match
{
scrutinee
,
arms
}
=>
{
this
.match_expr
(
destination
,
scope
,
expr_span
,
block
,
scrutinee
,
arms
)
this
.match_expr
(
destination
,
expr_span
,
block
,
scrutinee
,
arms
)
}
ExprKind
::
If
{
cond
,
then
,
else_opt
}
=>
{
let
place
=
unpack!
(
...
...
@@ -79,9 +63,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let
term
=
TerminatorKind
::
if_
(
this
.hir
.tcx
(),
operand
,
then_block
,
else_block
);
this
.cfg
.terminate
(
block
,
source_info
,
term
);
unpack!
(
then_block
=
this
.into
(
destination
,
scope
,
then_block
,
then
));
unpack!
(
then_block
=
this
.into
(
destination
,
then_block
,
then
));
else_block
=
if
let
Some
(
else_opt
)
=
else_opt
{
unpack!
(
this
.into
(
destination
,
None
,
else_block
,
else_opt
))
unpack!
(
this
.into
(
destination
,
else_block
,
else_opt
))
}
else
{
// Body of the `if` expression without an `else` clause must return `()`, thus
// we implicitly generate a `else {}` if it is not specified.
...
...
@@ -117,7 +101,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// This is an optimization. If the expression was a call then we already have an
// unreachable block. Don't bother to terminate it and create a new one.
schedule_drop
(
this
);
if
is_call
{
block
.unit
()
}
else
{
...
...
@@ -193,35 +176,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Start the loop.
this
.cfg
.goto
(
block
,
source_info
,
loop_block
);
this
.in_breakable_scope
(
Some
(
loop_block
),
destination
,
scope
,
expr_span
,
move
|
this
|
{
// conduct the test, if necessary
let
body_block
=
this
.cfg
.start_new_block
();
this
.cfg
.terminate
(
loop_block
,
source_info
,
TerminatorKind
::
FalseUnwind
{
real_target
:
body_block
,
unwind
:
None
},
);
this
.diverge_from
(
loop_block
);
// The “return” value of the loop body must always be an unit. We therefore
// introduce a unit temporary as the destination for the loop body.
let
tmp
=
this
.get_unit_temp
();
// Execute the body, branching back to the test.
// We don't need to provide a drop scope because `tmp`
// has type `()`.
let
body_block_end
=
unpack!
(
this
.into
(
tmp
,
None
,
body_block
,
body
));
this
.cfg
.goto
(
body_block_end
,
source_info
,
loop_block
);
schedule_drop
(
this
);
// Loops are only exited by `break` expressions.
None
},
)
this
.in_breakable_scope
(
Some
(
loop_block
),
destination
,
expr_span
,
move
|
this
|
{
// conduct the test, if necessary
let
body_block
=
this
.cfg
.start_new_block
();
this
.cfg
.terminate
(
loop_block
,
source_info
,
TerminatorKind
::
FalseUnwind
{
real_target
:
body_block
,
unwind
:
None
},
);
this
.diverge_from
(
loop_block
);
// The “return” value of the loop body must always be an unit. We therefore
// introduce a unit temporary as the destination for the loop body.
let
tmp
=
this
.get_unit_temp
();
// Execute the body, branching back to the test.
let
body_block_end
=
unpack!
(
this
.into
(
tmp
,
body_block
,
body
));
this
.cfg
.goto
(
body_block_end
,
source_info
,
loop_block
);
// Loops are only exited by `break` expressions.
None
})
}
ExprKind
::
Call
{
ty
:
_
,
fun
,
args
,
from_hir_call
,
fn_span
}
=>
{
let
fun
=
unpack!
(
block
=
this
.as_local_operand
(
block
,
fun
));
...
...
@@ -256,10 +230,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
},
);
this
.diverge_from
(
block
);
schedule_drop
(
this
);
success
.unit
()
}
ExprKind
::
Use
{
source
}
=>
this
.into
(
destination
,
scope
,
block
,
source
),
ExprKind
::
Use
{
source
}
=>
this
.into
(
destination
,
block
,
source
),
ExprKind
::
Borrow
{
arg
,
borrow_kind
}
=>
{
// We don't do this in `as_rvalue` because we use `as_place`
// for borrow expressions, so we cannot create an `RValue` that
...
...
@@ -348,7 +321,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
destination
,
Rvalue
::
Aggregate
(
adt
,
fields
),
);
schedule_drop
(
this
);
block
.unit
()
}
ExprKind
::
InlineAsm
{
template
,
operands
,
options
,
line_spans
}
=>
{
...
...
@@ -445,7 +417,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let
place
=
unpack!
(
block
=
this
.as_place
(
block
,
expr
));
let
rvalue
=
Rvalue
::
Use
(
this
.consume_by_copy_or_move
(
place
));
this
.cfg
.push_assign
(
block
,
source_info
,
destination
,
rvalue
);
schedule_drop
(
this
);
block
.unit
()
}
ExprKind
::
Index
{
..
}
|
ExprKind
::
Deref
{
..
}
|
ExprKind
::
Field
{
..
}
=>
{
...
...
@@ -463,7 +434,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let
place
=
unpack!
(
block
=
this
.as_place
(
block
,
expr
));
let
rvalue
=
Rvalue
::
Use
(
this
.consume_by_copy_or_move
(
place
));
this
.cfg
.push_assign
(
block
,
source_info
,
destination
,
rvalue
);
schedule_drop
(
this
);
block
.unit
()
}
...
...
@@ -478,7 +448,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
TerminatorKind
::
Yield
{
value
,
resume
,
resume_arg
:
destination
,
drop
:
None
},
);
this
.generator_drop_cleanup
(
block
);
schedule_drop
(
this
);
resume
.unit
()
}
...
...
@@ -510,7 +479,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let
rvalue
=
unpack!
(
block
=
this
.as_local_rvalue
(
block
,
expr
));
this
.cfg
.push_assign
(
block
,
source_info
,
destination
,
rvalue
);
schedule_drop
(
this
);
block
.unit
()
}
};
...
...
compiler/rustc_mir_build/src/build/into.rs
浏览文件 @
a71a8194
...
...
@@ -6,7 +6,6 @@
use
crate
::
build
::{
BlockAnd
,
Builder
};
use
crate
::
thir
::
*
;
use
rustc_middle
::
middle
::
region
;
use
rustc_middle
::
mir
::
*
;
pub
(
in
crate
::
build
)
trait
EvalInto
<
'tcx
>
{
...
...
@@ -14,7 +13,6 @@ fn eval_into(
self
,
builder
:
&
mut
Builder
<
'_
,
'tcx
>
,
destination
:
Place
<
'tcx
>
,
scope
:
Option
<
region
::
Scope
>
,
block
:
BasicBlock
,
)
->
BlockAnd
<
()
>
;
}
...
...
@@ -23,14 +21,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
crate
fn
into
<
E
>
(
&
mut
self
,
destination
:
Place
<
'tcx
>
,
scope
:
Option
<
region
::
Scope
>
,
block
:
BasicBlock
,
expr
:
E
,
)
->
BlockAnd
<
()
>
where
E
:
EvalInto
<
'tcx
>
,
{
expr
.eval_into
(
self
,
destination
,
scope
,
block
)
expr
.eval_into
(
self
,
destination
,
block
)
}
}
...
...
@@ -39,11 +36,10 @@ fn eval_into(
self
,
builder
:
&
mut
Builder
<
'_
,
'tcx
>
,
destination
:
Place
<
'tcx
>
,
scope
:
Option
<
region
::
Scope
>
,
block
:
BasicBlock
,
)
->
BlockAnd
<
()
>
{
let
expr
=
builder
.hir
.mirror
(
self
);
builder
.into_expr
(
destination
,
scope
,
block
,
expr
)
builder
.into_expr
(
destination
,
block
,
expr
)
}
}
...
...
@@ -52,9 +48,8 @@ fn eval_into(
self
,
builder
:
&
mut
Builder
<
'_
,
'tcx
>
,
destination
:
Place
<
'tcx
>
,
scope
:
Option
<
region
::
Scope
>
,
block
:
BasicBlock
,
)
->
BlockAnd
<
()
>
{
builder
.into_expr
(
destination
,
scope
,
block
,
self
)
builder
.into_expr
(
destination
,
block
,
self
)
}
}
compiler/rustc_mir_build/src/build/matches/mod.rs
浏览文件 @
a71a8194
...
...
@@ -87,7 +87,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
crate
fn
match_expr
(
&
mut
self
,
destination
:
Place
<
'tcx
>
,
destination_scope
:
Option
<
region
::
Scope
>
,
span
:
Span
,
mut
block
:
BasicBlock
,
scrutinee
:
ExprRef
<
'tcx
>
,
...
...
@@ -108,7 +107,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self
.lower_match_arms
(
destination
,
destination_scope
,
scrutinee_place
,
scrutinee_span
,
arm_candidates
,
...
...
@@ -215,13 +213,76 @@ fn lower_match_tree<'pat>(
}
}
/// 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 {:?}
\n
candidate = {:?}"
,
arm
,
candidate
);
let
arm_source_info
=
self
.source_info
(
arm
.span
);
let
arm_scope
=
(
arm
.scope
,
arm_source_info
);
self
.in_scope
(
arm_scope
,
arm
.lint_level
,
|
this
|
{
let
body
=
this
.hir
.mirror
(
arm
.body
.clone
());
let
scope
=
this
.declare_bindings
(
None
,
arm
.span
,
&
arm
.pattern
,
ArmHasGuard
(
arm
.guard
.is_some
()),
Some
((
Some
(
&
scrutinee_place
),
scrutinee_span
)),
);
let
arm_block
=
this
.bind_pattern
(
outer_source_info
,
candidate
,
arm
.guard
.as_ref
(),
&
fake_borrow_temps
,
scrutinee_span
,
Some
(
arm
.span
),
Some
(
arm
.scope
),
);
if
let
Some
(
source_scope
)
=
scope
{
this
.source_scope
=
source_scope
;
}
this
.into
(
destination
,
arm_block
,
body
)
})
})
.collect
();
// all the arm blocks will rejoin here
let
end_block
=
self
.cfg
.start_new_block
();
for
arm_block
in
arm_end_blocks
{
self
.cfg
.goto
(
unpack!
(
arm_block
),
outer_source_info
,
end_block
);
}
self
.source_scope
=
outer_source_info
.scope
;
end_block
.unit
()
}
/// Binds the variables and ascribes types for a given `match` arm or
/// `let` binding.
///
/// Also check if the guard matches, if it's provided.
/// `arm_scope` should be `Some` if and only if this is called for a
/// `match` arm.
crate
fn
bind_pattern
(
fn
bind_pattern
(
&
mut
self
,
outer_source_info
:
SourceInfo
,
candidate
:
Candidate
<
'_
,
'tcx
>
,
...
...
@@ -308,14 +369,13 @@ pub(super) fn expr_into_pattern(
PatKind
::
Binding
{
mode
:
BindingMode
::
ByValue
,
var
,
subpattern
:
None
,
..
}
=>
{
let
place
=
self
.storage_live_binding
(
block
,
var
,
irrefutable_pat
.span
,
OutsideGuard
,
true
);
let
region_scope
=
self
.hir.region_scope_tree
.var_scope
(
var
.local_id
);
unpack!
(
block
=
self
.into
(
place
,
Some
(
region_scope
),
block
,
initializer
));
unpack!
(
block
=
self
.into
(
place
,
block
,
initializer
));
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
let
source_info
=
self
.source_info
(
irrefutable_pat
.span
);
self
.cfg
.push_fake_read
(
block
,
source_info
,
FakeReadCause
::
ForLet
,
place
);
self
.schedule_drop_for_binding
(
var
,
irrefutable_pat
.span
,
OutsideGuard
);
block
.unit
()
}
...
...
@@ -342,10 +402,9 @@ pub(super) fn expr_into_pattern(
ascription
:
thir
::
pattern
::
Ascription
{
user_ty
:
pat_ascription_ty
,
variance
:
_
,
user_ty_span
},
}
=>
{
let
region_scope
=
self
.hir.region_scope_tree
.var_scope
(
var
.local_id
);
let
place
=
self
.storage_live_binding
(
block
,
var
,
irrefutable_pat
.span
,
OutsideGuard
,
true
);
unpack!
(
block
=
self
.into
(
place
,
Some
(
region_scope
),
block
,
initializer
));
unpack!
(
block
=
self
.into
(
place
,
block
,
initializer
));
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
let
pattern_source_info
=
self
.source_info
(
irrefutable_pat
.span
);
...
...
@@ -383,6 +442,7 @@ pub(super) fn expr_into_pattern(
},
);
self
.schedule_drop_for_binding
(
var
,
irrefutable_pat
.span
,
OutsideGuard
);
block
.unit
()
}
...
...
@@ -629,7 +689,7 @@ pub(super) fn visit_primary_bindings(
}
#[derive(Debug)]
pub
(
super
)
struct
Candidate
<
'pat
,
'tcx
>
{
struct
Candidate
<
'pat
,
'tcx
>
{
/// [`Span`] of the original pattern that gave rise to this candidate.
span
:
Span
,
...
...
@@ -1362,7 +1422,12 @@ fn test_candidates<'pat, 'b, 'c>(
match
test
.kind
{
TestKind
::
SwitchInt
{
switch_ty
,
ref
mut
options
}
=>
{
for
candidate
in
candidates
.iter
()
{
if
!
self
.add_cases_to_switch
(
&
match_place
,
candidate
,
switch_ty
,
options
)
{
if
!
self
.add_cases_to_switch
(
&
match_place
,
candidate
,
switch_ty
,
options
,
)
{
break
;
}
}
...
...
@@ -1777,11 +1842,14 @@ fn bind_and_guard_matched_candidate<'pat>(
// ```
//
// and that is clearly not correct.
let
by_value_bindings
=
parent_bindings
.iter
()
.flat_map
(|(
bindings
,
_
)|
bindings
)
.chain
(
&
candidate
.bindings
)
.filter
(|
binding
|
matches!
(
binding
.binding_mode
,
BindingMode
::
ByValue
));
let
by_value_bindings
=
parent_bindings
.iter
()
.flat_map
(|(
bindings
,
_
)|
bindings
)
.chain
(
&
candidate
.bindings
)
.filter
(|
binding
|
{
matches!
(
binding
.binding_mode
,
BindingMode
::
ByValue
)
});
// Read all of the by reference bindings to ensure that the
// place they refer to can't be modified by the guard.
for
binding
in
by_value_bindings
.clone
()
{
...
...
compiler/rustc_mir_build/src/build/mod.rs
浏览文件 @
a71a8194
...
...
@@ -76,9 +76,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
kind
:
hir
::
TraitItemKind
::
Const
(
ty
,
Some
(
body_id
)),
..
})
=>
(
*
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
),
};
...
...
@@ -186,7 +184,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
return_ty
,
return_ty_span
,
body
,
span_with_body
,
span_with_body
);
mir
.yield_ty
=
yield_ty
;
mir
...
...
@@ -584,7 +582,7 @@ fn construct_fn<'a, 'tcx, A>(
return_ty
:
Ty
<
'tcx
>
,
return_ty_span
:
Span
,
body
:
&
'tcx
hir
::
Body
<
'tcx
>
,
span_with_body
:
Span
,
span_with_body
:
Span
)
->
Body
<
'tcx
>
where
A
:
Iterator
<
Item
=
ArgInfo
<
'tcx
>>
,
...
...
@@ -618,12 +616,8 @@ fn construct_fn<'a, 'tcx, A>(
let
arg_scope_s
=
(
arg_scope
,
source_info
);
// Attribute epilogue to function's closing brace
let
fn_end
=
span_with_body
.shrink_to_hi
();
let
return_block
=
unpack!
(
builder
.in_breakable_scope
(
None
,
Place
::
return_place
(),
Some
(
call_site_scope
),
fn_end
,
|
builder
|
{
let
return_block
=
unpack!
(
builder
.in_breakable_scope
(
None
,
Place
::
return_place
(),
fn_end
,
|
builder
|
{
Some
(
builder
.in_scope
(
arg_scope_s
,
LintLevel
::
Inherited
,
|
builder
|
{
builder
.args_and_body
(
START_BLOCK
,
...
...
@@ -633,13 +627,11 @@ fn construct_fn<'a, 'tcx, A>(
&
body
.value
,
)
}))
},
));
}));
let
source_info
=
builder
.source_info
(
fn_end
);
builder
.cfg
.terminate
(
return_block
,
source_info
,
TerminatorKind
::
Return
);
let
should_abort
=
should_abort_on_panic
(
tcx
,
fn_def_id
,
abi
);
builder
.build_drop_trees
(
should_abort
);
builder
.unschedule_return_place_drop
();
return_block
.unit
()
}));
...
...
@@ -666,15 +658,12 @@ fn construct_const<'a, 'tcx>(
let
owner_id
=
tcx
.hir
()
.body_owner
(
body_id
);
let
def_id
=
tcx
.hir
()
.local_def_id
(
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
ast_expr
=
&
tcx
.hir
()
.body
(
body_id
)
.value
;
let
expr
=
builder
.hir
.mirror
(
ast_expr
);
// We don't provide a scope because we can't unwind in constants, so won't
// need to drop the return place.
unpack!
(
block
=
builder
.into_expr
(
Place
::
return_place
(),
None
,
block
,
expr
));
unpack!
(
block
=
builder
.into_expr
(
Place
::
return_place
(),
block
,
expr
));
let
source_info
=
builder
.source_info
(
span
);
builder
.cfg
.terminate
(
block
,
source_info
,
TerminatorKind
::
Return
);
...
...
@@ -709,8 +698,7 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
hir
::
BodyOwnerKind
::
Const
=>
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
);
// Some MIR passes will expect the number of parameters to match the
// function declaration.
...
...
@@ -953,9 +941,7 @@ fn args_and_body(
}
let
body
=
self
.hir
.mirror
(
ast_body
);
let
call_site
=
region
::
Scope
{
id
:
ast_body
.hir_id.local_id
,
data
:
region
::
ScopeData
::
CallSite
};
self
.into
(
Place
::
return_place
(),
Some
(
call_site
),
block
,
body
)
self
.into
(
Place
::
return_place
(),
block
,
body
)
}
fn
set_correct_source_scope_for_arg
(
...
...
compiler/rustc_mir_build/src/build/scope.rs
浏览文件 @
a71a8194
...
...
@@ -81,9 +81,8 @@
*/
use
crate
::
build
::
matches
::{
ArmHasGuard
,
Candidate
};
use
crate
::
build
::{
BlockAnd
,
BlockAndExtension
,
BlockFrame
,
Builder
,
CFG
};
use
crate
::
thir
::{
Arm
,
Expr
,
ExprRef
,
LintLevel
};
use
crate
::
thir
::{
Expr
,
ExprRef
,
LintLevel
};
use
rustc_data_structures
::
fx
::{
FxHashMap
,
FxHashSet
};
use
rustc_index
::
vec
::
IndexVec
;
use
rustc_middle
::
middle
::
region
;
...
...
@@ -156,8 +155,6 @@ struct BreakableScope<'tcx> {
/// The destination of the loop/block expression itself (i.e., where to put
/// the result of a `break` or `return` expression)
break_destination
:
Place
<
'tcx
>
,
/// The scope that the destination should have its drop scheduled in.
destination_scope
:
Option
<
region
::
Scope
>
,
/// Drops that happen on the `break`/`return` path.
break_drops
:
DropTree
,
/// Drops that happen on the `continue` path.
...
...
@@ -440,7 +437,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&
mut
self
,
loop_block
:
Option
<
BasicBlock
>
,
break_destination
:
Place
<
'tcx
>
,
destination_scope
:
Option
<
region
::
Scope
>
,
span
:
Span
,
f
:
F
,
)
->
BlockAnd
<
()
>
...
...
@@ -451,19 +447,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let
scope
=
BreakableScope
{
region_scope
,
break_destination
,
destination_scope
,
break_drops
:
DropTree
::
new
(),
continue_drops
:
loop_block
.map
(|
_
|
DropTree
::
new
()),
};
let
continue_block
=
loop_block
.map
(|
block
|
(
block
,
self
.diverge_cleanup
()));
self
.scopes.breakable_scopes
.push
(
scope
);
let
normal_exit_block
=
f
(
self
);
let
breakable_scope
=
self
.scopes.breakable_scopes
.pop
()
.unwrap
();
assert
!
(
breakable_scope
.region_scope
==
region_scope
);
if
let
Some
(
drops
)
=
breakable_scope
.continue_drops
{
self
.build_exit_tree
(
drops
,
continue_block
);
}
let
break_block
=
self
.build_exit_tree
(
breakable_scope
.break_drops
,
None
);
if
let
Some
(
drops
)
=
breakable_scope
.continue_drops
{
self
.build_exit_tree
(
drops
,
loop_block
);
}
match
(
normal_exit_block
,
break_block
)
{
(
Some
(
block
),
None
)
|
(
None
,
Some
(
block
))
=>
block
,
(
None
,
None
)
=>
self
.cfg
.start_new_block
()
.unit
(),
...
...
@@ -592,22 +584,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.rposition
(|
breakable_scope
|
breakable_scope
.region_scope
==
scope
)
.unwrap_or_else
(||
span_bug!
(
span
,
"no enclosing breakable scope found"
))
};
let
(
break_index
,
destination
,
dest_scope
)
=
match
target
{
let
(
break_index
,
destination
)
=
match
target
{
BreakableTarget
::
Return
=>
{
let
scope
=
&
self
.scopes.breakable_scopes
[
0
];
if
scope
.break_destination
!=
Place
::
return_place
()
{
span_bug!
(
span
,
"`return` in item with no return scope"
);
}
(
0
,
Some
(
scope
.break_destination
)
,
scope
.destination_scope
)
(
0
,
Some
(
scope
.break_destination
))
}
BreakableTarget
::
Break
(
scope
)
=>
{
let
break_index
=
get_scope_index
(
scope
);
let
scope
=
&
self
.scopes.breakable_scopes
[
break_index
];
(
break_index
,
Some
(
scope
.break_destination
)
,
scope
.destination_scope
)
(
break_index
,
Some
(
scope
.break_destination
))
}
BreakableTarget
::
Continue
(
scope
)
=>
{
let
break_index
=
get_scope_index
(
scope
);
(
break_index
,
None
,
None
)
(
break_index
,
None
)
}
};
...
...
@@ -615,10 +607,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if
let
Some
(
value
)
=
value
{
debug!
(
"stmt_expr Break val block_context.push(SubExpr)"
);
self
.block_context
.push
(
BlockFrame
::
SubExpr
);
unpack!
(
block
=
self
.into
(
destination
,
dest_scope
,
block
,
value
));
if
let
Some
(
scope
)
=
dest_scope
{
self
.unschedule_drop
(
scope
,
destination
.as_local
()
.unwrap
())
};
unpack!
(
block
=
self
.into
(
destination
,
block
,
value
));
self
.block_context
.pop
();
}
else
{
self
.cfg
.push_assign_unit
(
block
,
source_info
,
destination
,
self
.hir
.tcx
())
...
...
@@ -858,47 +847,14 @@ fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock {
span_bug!
(
span
,
"region scope {:?} not in scope to drop {:?}"
,
region_scope
,
local
);
}
/// Unschedule a drop. Used for `break`, `return` and `match` expressions,
/// where `record_operands_moved` is not powerful enough.
///
/// The given local is expected to have a value drop scheduled in the given
/// scope and for that drop to be the most recent thing scheduled in that
/// scope.
fn
unschedule_drop
(
&
mut
self
,
region_scope
:
region
::
Scope
,
local
:
Local
)
{
if
!
self
.hir
.needs_drop
(
self
.local_decls
[
local
]
.ty
)
{
return
;
}
for
scope
in
self
.scopes.scopes
.iter_mut
()
.rev
()
{
scope
.invalidate_cache
();
if
scope
.region_scope
==
region_scope
{
let
drop
=
scope
.drops
.pop
();
match
drop
{
Some
(
DropData
{
local
:
removed_local
,
kind
:
DropKind
::
Value
,
..
})
if
removed_local
==
local
=>
{
return
;
}
_
=>
bug!
(
"found wrong drop, expected value drop of {:?}, found {:?}"
,
local
,
drop
,
),
}
}
}
bug!
(
"region scope {:?} not in scope to unschedule drop of {:?}"
,
region_scope
,
local
);
}
/// Indicates that the "local operands" stored in `local` is
/// Indicates that the "local operand" stored in `local` is
/// *moved* at some point during execution (see `local_scope` for
/// more information about what a "local operand" is -- in short,
/// it's an intermediate operand created as part of preparing some
/// MIR instruction). We use this information to suppress
/// redundant drops. This results in less MIR, but also avoids spurious
/// borrow check errors (c.f. #64391).
/// redundant drops on the non-unwind paths. This results in less
/// MIR, but also avoids spurious borrow check errors
/// (c.f. #64391).
///
/// Example: when compiling the call to `foo` here:
///
...
...
@@ -1133,97 +1089,11 @@ fn diverge_cleanup(&mut self) -> DropIdx {
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 {:?}
\n
candidate = {:?}"
,
arm
,
candidate
);
if
first_arm
{
first_arm
=
false
;
}
else
if
let
Some
(
scope
)
=
destination_scope
{
self
.unschedule_drop
(
scope
,
destination
.as_local
()
.unwrap
());
}
let
arm_source_info
=
self
.source_info
(
arm
.span
);
let
arm_scope
=
(
arm
.scope
,
arm_source_info
);
self
.in_scope
(
arm_scope
,
arm
.lint_level
,
|
this
|
{
let
body
=
this
.hir
.mirror
(
arm
.body
.clone
());
let
scope
=
this
.declare_bindings
(
None
,
arm
.span
,
&
arm
.pattern
,
ArmHasGuard
(
arm
.guard
.is_some
()),
Some
((
Some
(
&
scrutinee_place
),
scrutinee_span
)),
);
let
arm_block
=
this
.bind_pattern
(
outer_source_info
,
candidate
,
arm
.guard
.as_ref
(),
&
fake_borrow_temps
,
scrutinee_span
,
Some
(
arm
.span
),
Some
(
arm
.scope
),
);
if
let
Some
(
source_scope
)
=
scope
{
this
.source_scope
=
source_scope
;
}
this
.into
(
destination
,
destination_scope
,
arm_block
,
body
)
})
})
.collect
();
// all the arm blocks will rejoin here
let
end_block
=
self
.cfg
.start_new_block
();
for
arm_block
in
arm_end_blocks
{
self
.cfg
.goto
(
unpack!
(
arm_block
),
outer_source_info
,
end_block
);
}
self
.source_scope
=
outer_source_info
.scope
;
end_block
.unit
()
}
/// Unschedules any drops in the top scope.
///
/// This is only needed for `match` arm scopes, because they have one
/// entrance per pattern, but only one exit.
pub
(
super
)
fn
clear_top_scope
(
&
mut
self
,
region_scope
:
region
::
Scope
)
{
crate
fn
clear_top_scope
(
&
mut
self
,
region_scope
:
region
::
Scope
)
{
let
top_scope
=
self
.scopes.scopes
.last_mut
()
.unwrap
();
assert_eq!
(
top_scope
.region_scope
,
region_scope
);
...
...
@@ -1231,18 +1101,6 @@ pub(super) fn clear_top_scope(&mut self, region_scope: region::Scope) {
top_scope
.drops
.clear
();
top_scope
.invalidate_cache
();
}
/// Unschedules the drop of the return place.
///
/// If the return type of a function requires drop, then we schedule it
/// in the outermost scope so that it's dropped if there's a panic while
/// we drop any local variables. But we don't want to drop it if we
/// return normally.
crate
fn
unschedule_return_place_drop
(
&
mut
self
)
{
assert_eq!
(
self
.scopes.scopes
.len
(),
1
);
assert
!
(
self
.scopes.scopes
[
0
]
.drops
.len
()
<=
1
);
self
.scopes.scopes
[
0
]
.drops
.clear
();
}
}
/// Builds drops for `pop_scope` and `leave_top_scope`.
...
...
@@ -1318,24 +1176,20 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
/// Build a drop tree for a breakable scope.
///
/// If `continue_block` is `Some`, then the tree is for `continue` inside a
/// loop. Otherwise this is for `break` or `return`. The `DropIdx` is the
/// next drop in the case that the drop tree unwinds. This is needed
/// because the drop of the break destination has already been scheduled
/// but it hasn't been initialized on the `continue` paths.
/// loop. Otherwise this is for `break` or `return`.
fn
build_exit_tree
(
&
mut
self
,
mut
drops
:
DropTree
,
continue_block
:
Option
<
(
BasicBlock
,
DropIdx
)
>
,
continue_block
:
Option
<
BasicBlock
>
,
)
->
Option
<
BlockAnd
<
()
>>
{
let
mut
blocks
=
IndexVec
::
from_elem
(
None
,
&
drops
.drops
);
blocks
[
ROOT_NODE
]
=
continue_block
.map
(|(
block
,
_
)|
block
)
;
blocks
[
ROOT_NODE
]
=
continue_block
;
drops
.build_mir
::
<
ExitScopes
>
(
&
mut
self
.cfg
,
&
mut
blocks
);
// Link the exit drop tree to unwind drop tree.
if
drops
.drops
.iter
()
.any
(|(
drop
,
_
)|
drop
.kind
==
DropKind
::
Value
)
{
let
unwind_target
=
continue_block
.map_or_else
(||
self
.diverge_cleanup
(),
|(
_
,
unwind_target
)|
unwind_target
);
let
unwind_target
=
self
.diverge_cleanup
();
let
mut
unwind_indices
=
IndexVec
::
from_elem_n
(
unwind_target
,
1
);
for
(
drop_idx
,
drop_data
)
in
drops
.drops
.iter_enumerated
()
.skip
(
1
)
{
match
drop_data
.0
.kind
{
...
...
library/alloc/src/collections/btree/map/tests.rs
浏览文件 @
a71a8194
...
...
@@ -1882,7 +1882,7 @@ fn drop(&mut self) {
catch_unwind
(
move
||
left
.append
(
&
mut
right
))
.unwrap_err
();
assert_eq!
(
DROPS
.load
(
SeqCst
),
5
);
assert_eq!
(
DROPS
.load
(
SeqCst
),
4
);
// Rust issue #47949 ate one little piggy
}
#[test]
...
...
src/test/mir-opt/inline/inline_diverging.h.Inline.diff
浏览文件 @
a71a8194
...
...
@@ -5,19 +5,18 @@
let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:21:12: 21:12
let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _7: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _8: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _9: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22
+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _5: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _6: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ let mut _7: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 2 {
+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 3 {
+ debug b => _
7
; // in scope 3 at $DIR/inline-diverging.rs:22:5: 22:22
+ debug b => _
6
; // in scope 3 at $DIR/inline-diverging.rs:22:5: 22:22
+ }
+ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:22:5: 22:22
+ scope 7 (inlined sleep) { // at $DIR/inline-diverging.rs:22:5: 22:22
...
...
@@ -41,12 +40,12 @@
- // mir::Constant
// + span: $DIR/inline-diverging.rs:22:16: 22:21
// + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) }
+ StorageLive(_
7
); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_
6
); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_
8
); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ _
8
= const (); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_
7
); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ _
7
= const (); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22
+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:22:5: 22:22
}
...
...
src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
浏览文件 @
a71a8194
...
...
@@ -30,7 +30,7 @@ fn test() -> Option<Box<u32>> {
StorageLive(_3); // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
StorageLive(_4); // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
_4 = Option::<u32>::None; // scope 0 at $DIR/issue-62289.rs:9:15: 9:19
_3 = <Option<u32> as Try>::into_result(move _4) -> [return: bb1, unwind: bb
10
]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
_3 = <Option<u32> as Try>::into_result(move _4) -> [return: bb1, unwind: bb
9
]; // scope 0 at $DIR/issue-62289.rs:9:15: 9:20
// mir::Constant
// + span: $DIR/issue-62289.rs:9:15: 9:20
// + literal: Const { ty: fn(std::option::Option<u32>) -> std::result::Result<<std::option::Option<u32> as std::ops::Try>::Ok, <std::option::Option<u32> as std::ops::Try>::Error> {<std::option::Option<u32> as std::ops::Try>::into_result}, val: Value(Scalar(<ZST>)) }
...
...
@@ -65,7 +65,7 @@ fn test() -> Option<Box<u32>> {
StorageLive(_8); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
StorageLive(_9); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_9 = _6; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_8 = <NoneError as From<NoneError>>::from(move _9) -> [return: bb5, unwind: bb
10
]; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_8 = <NoneError as From<NoneError>>::from(move _9) -> [return: bb5, unwind: bb
9
]; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
// mir::Constant
// + span: $DIR/issue-62289.rs:9:19: 9:20
// + literal: Const { ty: fn(std::option::NoneError) -> std::option::NoneError {<std::option::NoneError as std::convert::From<std::option::NoneError>>::from}, val: Value(Scalar(<ZST>)) }
...
...
@@ -73,7 +73,7 @@ fn test() -> Option<Box<u32>> {
bb5: {
StorageDead(_9); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
_0 = <Option<Box<u32>> as Try>::from_error(move _8) -> [return: bb6, unwind: bb
10
]; // scope 2 at $DIR/issue-62289.rs:9:15: 9:20
_0 = <Option<Box<u32>> as Try>::from_error(move _8) -> [return: bb6, unwind: bb
9
]; // scope 2 at $DIR/issue-62289.rs:9:15: 9:20
// mir::Constant
// + span: $DIR/issue-62289.rs:9:15: 9:20
// + literal: Const { ty: fn(<std::option::Option<std::boxed::Box<u32>> as std::ops::Try>::Error) -> std::option::Option<std::boxed::Box<u32>> {<std::option::Option<std::boxed::Box<u32>> as std::ops::Try>::from_error}, val: Value(Scalar(<ZST>)) }
...
...
@@ -82,7 +82,7 @@ fn test() -> Option<Box<u32>> {
bb6: {
StorageDead(_8); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20
StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20
drop(_2) ->
[return: bb7, unwind: bb9];
// scope 0 at $DIR/issue-62289.rs:9:20: 9:21
drop(_2) ->
bb7;
// scope 0 at $DIR/issue-62289.rs:9:20: 9:21
}
bb7: {
...
...
@@ -97,14 +97,10 @@ fn test() -> Option<Box<u32>> {
}
bb9 (cleanup): {
drop(_
0) -> bb11; // scope 0 at $DIR/issue-62289.rs:10:1: 10:2
drop(_
2) -> bb10; // scope 0 at $DIR/issue-62289.rs:9:20: 9:21
}
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
}
}
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
浏览文件 @
a71a8194
...
...
@@ -19,12 +19,12 @@
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
19| 2|}
------------------
| used_crate::used_only_from_bin_crate_generic_function::<&
alloc::vec::Vec<i32>
>:
| used_crate::used_only_from_bin_crate_generic_function::<&
str
>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
------------------
| used_crate::used_only_from_bin_crate_generic_function::<&
str
>:
| used_crate::used_only_from_bin_crate_generic_function::<&
alloc::vec::Vec<i32>
>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
...
...
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.executor-block_on.-------.InstrumentCoverage.0.html
浏览文件 @
a71a8194
...
...
@@ -70,166 +70,166 @@ For revisions in Pull Requests (PR):
</head>
<body>
<div
class=
"code"
style=
"counter-reset: line 109"
><span
class=
"line"
>
<span><span
class=
"code even"
style=
"--layer: 1"
title=
"111:54-111:65: @0[2]: _3 = &mut _1
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
3
]
111:35-111:66: @0.Call: _2 = Pin::<&mut F>::new_unchecked(move _3) -> [return: bb1, unwind: bb2
0
]
111:13-111:23: @1[1]: FakeRead(ForLet, _2)
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
3
]
119:60-119:77: @1.Call: _6 = null::<()>() -> [return: bb2, unwind: bb2
0
]
119:80-119:86: @2[3]: _9 = const {alloc0: &RawWakerVTable}
119:79-119:86: @2[4]: _8 = &(*_9)
119:79-119:86: @2[5]: _7 = &(*_8)
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
3
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
3
]
119:46-119:87: @2.Call: _5 = RawWaker::new(move _6, move _7) -> [return: bb3, unwind: bb2
0
]
119:30-119:88: @3.Call: _4 = Waker::from_raw(move _5) -> [return: bb4, unwind: bb2
0
]
119:13-119:18: @4[1]: FakeRead(ForLet, _4)
120:47-120:53: @4[7]: _12 = &_4
120:47-120:53: @4[8]: _11 = &(*_12)
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
22
]
120:27-120:54: @4.Call: _10 = Context::from_waker(move _11) -> [return: bb5, unwind: bb
19
]
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"
>
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
123:39-123:54: @7.Call: _15 = Pin::<&mut F>::as_mut(move _16) -> [return: bb8, unwind: bb
22
]
123:39-123:54: @7.Call: _15 = Pin::<&mut F>::as_mut(move _16) -> [return: bb8, unwind: bb
19
]
123:60-123:72: @8[3]: _18 = &mut _10
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: bb
22
]
123:39-123:73: @8.Call: _14 = <F as Future>::poll(move _15, move _17) -> [return: bb9, unwind: bb
19
]
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"
>
}
</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>
...
...
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.async/async.main.-------.InstrumentCoverage.0.html
浏览文件 @
a71a8194
...
...
@@ -69,9 +69,9 @@ For revisions in Pull Requests (PR):
</style>
</head>
<body>
<div
class=
"code"
style=
"counter-reset: line 92"
><span
class=
"line"
><span><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
><span
class=
"annotation"
>
@0,1,2,3,4,5,6,7,8,9,10,11,12,13⦊
</span>
fn main() {
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
>
let _ = g(10);
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
>
let _ = h(9);
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
>
let mut future = Box::pin(i(8));
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
>
j(7);
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
>
l(6);
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
>
let _ = m(5);
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
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]
93:11-101:2: @12[2]: _0 = const ()
101:2-101:2: @13.Return: return"
>
executor::block_on(future.as_mut());
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"94:13-94:18: @0.Call: _1 = g(const 10_u8) -> [return: bb1, unwind: bb1
5
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
5
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
5
]
<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: bb1
6
]
95:13-95:17: @2.Call: _2 = h(const 9_usize) -> [return: bb3, unwind: bb1
6
]
96:31-96:35: @4.Call: _4 = i(const 8_u8) -> [return: bb5, unwind: bb1
6
]
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)
97:5-97:9: @6.Call: _5 = j(const 7_u8) -> [return: bb7, unwind: bb14]
...
...
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html
浏览文件 @
a71a8194
...
...
@@ -78,6 +78,7 @@ For revisions in Pull Requests (PR):
100:12-100:20: @0[5]: _5 = (*((*_1).0: &bool))"
>
let mut countdown = 0;
</span></span>
<span
class=
"line"
><span
class=
"code even"
style=
"--layer: 1"
title=
"99:29-99:30: @0[1]: _3 = const 0_i32
99:13-99:26: @0[2]: FakeRead(ForLet, _3)
<<<<<<< HEAD
100:12-100:20: @0[5]: _5 = (*((*_1).0: &bool))"
>
if is_false
<span
class=
"annotation"
>
⦉@0
</span></span></span><span
class=
"code"
style=
"--layer: 0"
>
</span><span><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @1[0]: _3 = const 10_i32
100:21-102:10: @1[1]: _4 = const ()"
><span
class=
"annotation"
>
@1⦊
</span>
{
</span></span>
<span
class=
"line"
><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @1[0]: _3 = const 10_i32
...
...
@@ -124,5 +125,102 @@ For revisions in Pull Requests (PR):
103:9-103:29: @6[1]: FakeRead(ForLet, _6)
103:9-103:29: @6[6]: _0 = move _6
104:6-104:6: @7.Return: return"
>
}
<span
class=
"annotation"
>
⦉@3,4,5,6,7
</span></span></span></span></div>
||||||| parent of 3873f4c114a... Revert "Avoid leaking block expression values"
100:12-100:20: @0[5]: _5 = (*((*_1).0:
&
bool))
100:12-100:20: @0[6]: FakeRead(ForMatchedPlace, _5)"> if is_false
<span
class=
"annotation"
>
⦉@0
</span></span></span><span
class=
"code"
style=
"--layer: 0"
>
</span><span><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @3[0]: _3 = const 10_i32
100:21-102:10: @3[1]: _4 = const ()"
><span
class=
"annotation"
>
@1,3⦊
</span>
{
</span></span>
<span
class=
"line"
><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @3[0]: _3 = const 10_i32
100:21-102:10: @3[1]: _4 = const ()"
>
countdown = 10;
</span></span>
<span
class=
"line"
><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @3[0]: _3 = const 10_i32
100:21-102:10: @3[1]: _4 = const ()"
>
}
<span
class=
"annotation"
>
⦉@1,3
</span></span></span><span><span
class=
"code even"
style=
"--layer: 1"
title=
"102:10-102:10: @2[0]: _4 = const ()"
><span
class=
"annotation"
>
@2⦊
</span>
‸
<span
class=
"annotation"
>
⦉@2
</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 odd"
style=
"--layer: 1"
title=
"103:17-103:23: @4[7]: _22 = const main::{closure#2}::promoted[0]
103:17-103:23: @4[8]: _10 = &(*_22)
103:17-103:23: @4[9]: _9 = &(*_10)
103:17-103:23: @4[10]: _8 = move _9 as &[&str] (Pointer(Unsize))
103:25-103:28: @4[18]: _17 = &_2
103:9-103:29: @4[19]: _16 = (move _17,)
103:9-103:29: @4[21]: FakeRead(ForMatchedPlace, _16)
103:9-103:29: @4[23]: _18 = (_16.0: &&str)
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.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[5]: _14 = &_15
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.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: bb10]
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
103:9-103:29: @7[6]: _0 = move _6
104:6-104:6: @8.Return: return"
><span
class=
"annotation"
>
@4,5,6,7,8⦊
</span>
format!("'{}'", val)
</span></span>
<span
class=
"line"
><span
class=
"code odd"
style=
"--layer: 1"
title=
"103:17-103:23: @4[7]: _22 = const main::{closure#2}::promoted[0]
103:17-103:23: @4[8]: _10 = &(*_22)
103:17-103:23: @4[9]: _9 = &(*_10)
103:17-103:23: @4[10]: _8 = move _9 as &[&str] (Pointer(Unsize))
103:25-103:28: @4[18]: _17 = &_2
103:9-103:29: @4[19]: _16 = (move _17,)
103:9-103:29: @4[21]: FakeRead(ForMatchedPlace, _16)
103:9-103:29: @4[23]: _18 = (_16.0: &&str)
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.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[5]: _14 = &_15
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.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: bb10]
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
103:9-103:29: @7[6]: _0 = move _6
104:6-104:6: @8.Return: return"
>
}
<span
class=
"annotation"
>
⦉@4,5,6,7,8
</span></span></span></span></div>
=======
100:12-100:20: @0[5]: _5 = (*((*_1).0:
&
bool))
100:12-100:20: @0[6]: FakeRead(ForMatchedPlace, _5)"> if is_false
<span
class=
"annotation"
>
⦉@0
</span></span></span><span
class=
"code"
style=
"--layer: 0"
>
</span><span><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @3[0]: _3 = const 10_i32
100:21-102:10: @3[1]: _4 = const ()"
><span
class=
"annotation"
>
@1,3⦊
</span>
{
</span></span>
<span
class=
"line"
><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @3[0]: _3 = const 10_i32
100:21-102:10: @3[1]: _4 = const ()"
>
countdown = 10;
</span></span>
<span
class=
"line"
><span
class=
"code odd"
style=
"--layer: 1"
title=
"101:13-101:27: @3[0]: _3 = const 10_i32
100:21-102:10: @3[1]: _4 = const ()"
>
}
<span
class=
"annotation"
>
⦉@1,3
</span></span></span><span><span
class=
"code even"
style=
"--layer: 1"
title=
"102:10-102:10: @2[0]: _4 = const ()"
><span
class=
"annotation"
>
@2⦊
</span>
‸
<span
class=
"annotation"
>
⦉@2
</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 odd"
style=
"--layer: 1"
title=
"103:17-103:23: @4[7]: _22 = const main::{closure#2}::promoted[0]
103:17-103:23: @4[8]: _10 = &(*_22)
103:17-103:23: @4[9]: _9 = &(*_10)
103:17-103:23: @4[10]: _8 = move _9 as &[&str] (Pointer(Unsize))
103:25-103:28: @4[18]: _17 = &_2
103:9-103:29: @4[19]: _16 = (move _17,)
103:9-103:29: @4[21]: FakeRead(ForMatchedPlace, _16)
103:9-103:29: @4[23]: _18 = (_16.0: &&str)
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.Call: _19 = ArgumentV1::new::<&str>(move _20, move _21) -> [return: bb5, unwind: bb9]
103:9-103:29: @5[2]: _15 = [move _19]
103:9-103:29: @5[5]: _14 = &_15
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.Call: _7 = Arguments::new_v1(move _8, move _12) -> [return: bb6, unwind: bb9]
103:9-103:29: @6.Call: _6 = format(move _7) -> [return: bb7, unwind: bb9]
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
103:9-103:29: @7[6]: _0 = move _6
104:6-104:6: @8.Return: return"
><span
class=
"annotation"
>
@4,5,6,7,8⦊
</span>
format!("'{}'", val)
</span></span>
<span
class=
"line"
><span
class=
"code odd"
style=
"--layer: 1"
title=
"103:17-103:23: @4[7]: _22 = const main::{closure#2}::promoted[0]
103:17-103:23: @4[8]: _10 = &(*_22)
103:17-103:23: @4[9]: _9 = &(*_10)
103:17-103:23: @4[10]: _8 = move _9 as &[&str] (Pointer(Unsize))
103:25-103:28: @4[18]: _17 = &_2
103:9-103:29: @4[19]: _16 = (move _17,)
103:9-103:29: @4[21]: FakeRead(ForMatchedPlace, _16)
103:9-103:29: @4[23]: _18 = (_16.0: &&str)
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.Call: _19 = ArgumentV1::new::<&str>(move _20, move _21) -> [return: bb5, unwind: bb9]
103:9-103:29: @5[2]: _15 = [move _19]
103:9-103:29: @5[5]: _14 = &_15
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.Call: _7 = Arguments::new_v1(move _8, move _12) -> [return: bb6, unwind: bb9]
103:9-103:29: @6.Call: _6 = format(move _7) -> [return: bb7, unwind: bb9]
103:9-103:29: @7[1]: FakeRead(ForLet, _6)
103:9-103:29: @7[6]: _0 = move _6
104:6-104:6: @8.Return: return"
>
}
<span
class=
"annotation"
>
⦉@4,5,6,7,8
</span></span></span></span></div>
>>>>>>> 3873f4c114a... Revert "Avoid leaking block expression values"
</body>
</html>
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html
浏览文件 @
a71a8194
此差异已折叠。
点击以展开。
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.used_crate/used_crate.use_this_lib_crate.-------.InstrumentCoverage.0.html
浏览文件 @
a71a8194
此差异已折叠。
点击以展开。
src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.uses_crate/uses_crate.main.-------.InstrumentCoverage.0.html
浏览文件 @
a71a8194
此差异已折叠。
点击以展开。
src/test/ui/drop/dynamic-drop-async.rs
浏览文件 @
a71a8194
...
...
@@ -43,7 +43,6 @@ fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
/// The `failing_op`-th operation will panic.
struct
Allocator
{
data
:
RefCell
<
Vec
<
bool
>>
,
name
:
&
'static
str
,
failing_op
:
usize
,
cur_ops
:
Cell
<
usize
>
,
}
...
...
@@ -55,28 +54,23 @@ impl Drop for Allocator {
fn
drop
(
&
mut
self
)
{
let
data
=
self
.data
.borrow
();
if
data
.iter
()
.any
(|
d
|
*
d
)
{
panic!
(
"missing free
in {:?}: {:?}"
,
self
.name
,
data
);
panic!
(
"missing free
: {:?}"
,
data
);
}
}
}
impl
Allocator
{
fn
new
(
failing_op
:
usize
,
name
:
&
'static
str
)
->
Self
{
Allocator
{
failing_op
,
name
,
cur_ops
:
Cell
::
new
(
0
),
data
:
RefCell
::
new
(
vec!
[]),
}
fn
new
(
failing_op
:
usize
)
->
Self
{
Allocator
{
failing_op
,
cur_ops
:
Cell
::
new
(
0
),
data
:
RefCell
::
new
(
vec!
[])
}
}
fn
alloc
(
self
:
&
Rc
<
Allocator
>
)
->
impl
Future
<
Output
=
Ptr
>
+
'static
{
fn
alloc
(
&
self
)
->
impl
Future
<
Output
=
Ptr
<
'_
>>
+
'_
{
self
.fallible_operation
();
let
mut
data
=
self
.data
.borrow_mut
();
let
addr
=
data
.len
();
data
.push
(
true
);
Defer
{
ready
:
false
,
value
:
Some
(
Ptr
(
addr
,
self
.clone
()
))
}
Defer
{
ready
:
false
,
value
:
Some
(
Ptr
(
addr
,
self
))
}
}
fn
fallible_operation
(
&
self
)
{
self
.cur_ops
.set
(
self
.cur_ops
.get
()
+
1
);
...
...
@@ -89,11 +83,11 @@ fn fallible_operation(&self) {
// Type that tracks whether it was dropped and can panic when it's created or
// destroyed.
struct
Ptr
(
usize
,
Rc
<
Allocator
>
);
impl
Drop
for
Ptr
{
struct
Ptr
<
'a
>
(
usize
,
&
'a
Allocator
);
impl
<
'a
>
Drop
for
Ptr
<
'a
>
{
fn
drop
(
&
mut
self
)
{
match
self
.1
.data
.borrow_mut
()[
self
.0
]
{
false
=>
panic!
(
"double free
in {:?} at index {:?}"
,
self
.1
.name
,
self
.0
),
false
=>
panic!
(
"double free
at index {:?}"
,
self
.0
),
ref
mut
d
=>
*
d
=
false
,
}
...
...
@@ -117,7 +111,7 @@ async fn dynamic_drop(a: Rc<Allocator>, c: bool) {
};
}
struct
TwoPtrs
(
Ptr
,
Ptr
);
struct
TwoPtrs
<
'a
>
(
Ptr
<
'a
>
,
Ptr
<
'a
>
);
async
fn
struct_dynamic_drop
(
a
:
Rc
<
Allocator
>
,
c0
:
bool
,
c1
:
bool
,
c
:
bool
)
{
for
i
in
0
..
2
{
let
x
;
...
...
@@ -238,62 +232,21 @@ async fn move_ref_pattern(a: Rc<Allocator>) {
a
.alloc
()
.await
;
}
async
fn
panic_after_return
(
a
:
Rc
<
Allocator
>
,
c
:
bool
)
->
(
Ptr
,)
{
a
.alloc
()
.await
;
let
p
=
a
.alloc
()
.await
;
if
c
{
a
.alloc
()
.await
;
let
q
=
a
.alloc
()
.await
;
// We use a return type that isn't used anywhere else to make sure that
// the return place doesn't incorrectly end up in the generator state.
return
(
a
.alloc
()
.await
,);
}
(
a
.alloc
()
.await
,)
}
async
fn
panic_after_init_by_loop
(
a
:
Rc
<
Allocator
>
)
{
a
.alloc
()
.await
;
let
p
=
a
.alloc
()
.await
;
let
q
=
loop
{
a
.alloc
()
.await
;
let
r
=
a
.alloc
()
.await
;
break
a
.alloc
()
.await
;
};
}
async
fn
panic_after_init_by_match_with_bindings_and_guard
(
a
:
Rc
<
Allocator
>
,
b
:
bool
)
{
a
.alloc
()
.await
;
let
p
=
a
.alloc
()
.await
;
let
q
=
match
a
.alloc
()
.await
{
ref
_
x
if
b
=>
{
a
.alloc
()
.await
;
let
r
=
a
.alloc
()
.await
;
a
.alloc
()
.await
}
_
x
=>
{
a
.alloc
()
.await
;
let
r
=
a
.alloc
()
.await
;
a
.alloc
()
.await
},
};
}
fn
run_test
<
F
,
G
,
O
>
(
cx
:
&
mut
Context
<
'_
>
,
ref
f
:
F
,
name
:
&
'static
str
)
fn
run_test
<
F
,
G
>
(
cx
:
&
mut
Context
<
'_
>
,
ref
f
:
F
)
where
F
:
Fn
(
Rc
<
Allocator
>
)
->
G
,
G
:
Future
<
Output
=
O
>
,
G
:
Future
<
Output
=
()
>
,
{
for
polls
in
0
..
{
// Run without any panics to find which operations happen after the
// penultimate `poll`.
let
first_alloc
=
Rc
::
new
(
Allocator
::
new
(
usize
::
MAX
,
name
));
let
first_alloc
=
Rc
::
new
(
Allocator
::
new
(
usize
::
MAX
));
let
mut
fut
=
Box
::
pin
(
f
(
first_alloc
.clone
()));
let
mut
ops_before_last_poll
=
0
;
let
mut
completed
=
false
;
for
_
in
0
..
polls
{
ops_before_last_poll
=
first_alloc
.cur_ops
.get
();
if
let
Poll
::
Ready
(
_
)
=
fut
.as_mut
()
.poll
(
cx
)
{
if
let
Poll
::
Ready
(
()
)
=
fut
.as_mut
()
.poll
(
cx
)
{
completed
=
true
;
}
}
...
...
@@ -302,7 +255,7 @@ fn run_test<F, G, O>(cx: &mut Context<'_>, ref f: F, name: &'static str)
// Start at `ops_before_last_poll` so that we will always be able to
// `poll` the expected number of times.
for
failing_op
in
ops_before_last_poll
..
first_alloc
.cur_ops
.get
()
{
let
alloc
=
Rc
::
new
(
Allocator
::
new
(
failing_op
+
1
,
name
));
let
alloc
=
Rc
::
new
(
Allocator
::
new
(
failing_op
+
1
));
let
f
=
&
f
;
let
cx
=
&
mut
*
cx
;
let
result
=
panic
::
catch_unwind
(
panic
::
AssertUnwindSafe
(
move
||
{
...
...
@@ -332,58 +285,48 @@ fn clone_waker(data: *const ()) -> RawWaker {
RawWaker
::
new
(
data
,
&
RawWakerVTable
::
new
(
clone_waker
,
drop
,
drop
,
drop
))
}
macro_rules!
run_test
{
(
$ctxt:expr
,
$e:expr
)
=>
{
run_test
(
$ctxt
,
$e
,
stringify!
(
$e
));
};
}
fn
main
()
{
let
waker
=
unsafe
{
Waker
::
from_raw
(
clone_waker
(
ptr
::
null
()))
};
let
context
=
&
mut
Context
::
from_waker
(
&
waker
);
run_test!
(
context
,
|
a
|
dynamic_init
(
a
,
false
));
run_test!
(
context
,
|
a
|
dynamic_init
(
a
,
true
));
run_test!
(
context
,
|
a
|
dynamic_drop
(
a
,
false
));
run_test!
(
context
,
|
a
|
dynamic_drop
(
a
,
true
));
run_test!
(
context
,
|
a
|
assignment
(
a
,
false
,
false
));
run_test!
(
context
,
|
a
|
assignment
(
a
,
false
,
true
));
run_test!
(
context
,
|
a
|
assignment
(
a
,
true
,
false
));
run_test!
(
context
,
|
a
|
assignment
(
a
,
true
,
true
));
run_test!
(
context
,
|
a
|
array_simple
(
a
));
run_test!
(
context
,
|
a
|
vec_simple
(
a
));
run_test!
(
context
,
|
a
|
vec_unreachable
(
a
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
false
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
true
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
false
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
true
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
false
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
true
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
false
));
run_test!
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
true
));
run_test!
(
context
,
|
a
|
field_assignment
(
a
,
false
));
run_test!
(
context
,
|
a
|
field_assignment
(
a
,
true
));
run_test!
(
context
,
|
a
|
mixed_drop_and_nondrop
(
a
));
run_test!
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
0
));
run_test!
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
1
));
run_test!
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
2
));
run_test!
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
3
));
run_test!
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
true
));
run_test!
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
false
));
run_test!
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
true
));
run_test!
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
false
));
run_test!
(
context
,
|
a
|
subslice_pattern_reassign
(
a
));
run_test!
(
context
,
|
a
|
move_ref_pattern
(
a
));
run_test!
(
context
,
|
a
|
panic_after_return
(
a
,
false
));
run_test!
(
context
,
|
a
|
panic_after_return
(
a
,
true
));
run_test!
(
context
,
|
a
|
panic_after_init_by_loop
(
a
));
run_test!
(
context
,
|
a
|
panic_after_init_by_match_with_bindings_and_guard
(
a
,
false
));
run_test!
(
context
,
|
a
|
panic_after_init_by_match_with_bindings_and_guard
(
a
,
true
));
run_test
(
context
,
|
a
|
dynamic_init
(
a
,
false
));
run_test
(
context
,
|
a
|
dynamic_init
(
a
,
true
));
run_test
(
context
,
|
a
|
dynamic_drop
(
a
,
false
));
run_test
(
context
,
|
a
|
dynamic_drop
(
a
,
true
));
run_test
(
context
,
|
a
|
assignment
(
a
,
false
,
false
));
run_test
(
context
,
|
a
|
assignment
(
a
,
false
,
true
));
run_test
(
context
,
|
a
|
assignment
(
a
,
true
,
false
));
run_test
(
context
,
|
a
|
assignment
(
a
,
true
,
true
));
run_test
(
context
,
|
a
|
array_simple
(
a
));
run_test
(
context
,
|
a
|
vec_simple
(
a
));
run_test
(
context
,
|
a
|
vec_unreachable
(
a
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
false
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
true
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
false
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
true
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
false
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
true
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
false
));
run_test
(
context
,
|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
true
));
run_test
(
context
,
|
a
|
field_assignment
(
a
,
false
));
run_test
(
context
,
|
a
|
field_assignment
(
a
,
true
));
run_test
(
context
,
|
a
|
mixed_drop_and_nondrop
(
a
));
run_test
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
0
));
run_test
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
1
));
run_test
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
2
));
run_test
(
context
,
|
a
|
slice_pattern_one_of
(
a
,
3
));
run_test
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
true
));
run_test
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
false
));
run_test
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
true
));
run_test
(
context
,
|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
false
));
run_test
(
context
,
|
a
|
subslice_pattern_reassign
(
a
));
run_test
(
context
,
|
a
|
move_ref_pattern
(
a
));
}
src/test/ui/drop/dynamic-drop.rs
浏览文件 @
a71a8194
...
...
@@ -3,6 +3,7 @@
#![feature(generators,
generator_trait)]
#![feature(bindings_after_at)]
#![allow(unused_assignments)]
#![allow(unused_variables)]
...
...
@@ -16,7 +17,6 @@
struct
Allocator
{
data
:
RefCell
<
Vec
<
bool
>>
,
name
:
&
'static
str
,
failing_op
:
usize
,
cur_ops
:
Cell
<
usize
>
,
}
...
...
@@ -28,18 +28,17 @@ impl Drop for Allocator {
fn
drop
(
&
mut
self
)
{
let
data
=
self
.data
.borrow
();
if
data
.iter
()
.any
(|
d
|
*
d
)
{
panic!
(
"missing free
in {:?}: {:?}"
,
self
.name
,
data
);
panic!
(
"missing free
: {:?}"
,
data
);
}
}
}
impl
Allocator
{
fn
new
(
failing_op
:
usize
,
name
:
&
'static
str
)
->
Self
{
fn
new
(
failing_op
:
usize
)
->
Self
{
Allocator
{
failing_op
:
failing_op
,
cur_ops
:
Cell
::
new
(
0
),
data
:
RefCell
::
new
(
vec!
[]),
name
,
data
:
RefCell
::
new
(
vec!
[])
}
}
fn
alloc
(
&
self
)
->
Ptr
<
'_
>
{
...
...
@@ -54,17 +53,33 @@ fn alloc(&self) -> Ptr<'_> {
data
.push
(
true
);
Ptr
(
addr
,
self
)
}
// FIXME(#47949) Any use of this indicates a bug in rustc: we should never
// be leaking values in the cases here.
//
// Creates a `Ptr<'_>` and checks that the allocated value is leaked if the
// `failing_op` is in the list of exception.
fn
alloc_leaked
(
&
self
,
exceptions
:
Vec
<
usize
>
)
->
Ptr
<
'_
>
{
let
ptr
=
self
.alloc
();
if
exceptions
.iter
()
.any
(|
operation
|
*
operation
==
self
.failing_op
)
{
let
mut
data
=
self
.data
.borrow_mut
();
data
[
ptr
.0
]
=
false
;
}
ptr
}
}
struct
Ptr
<
'a
>
(
usize
,
&
'a
Allocator
);
impl
<
'a
>
Drop
for
Ptr
<
'a
>
{
fn
drop
(
&
mut
self
)
{
match
self
.1
.data
.borrow_mut
()[
self
.0
]
{
false
=>
panic!
(
"double free in {:?} at index {:?}"
,
self
.1
.name
,
self
.0
),
ref
mut
d
=>
*
d
=
false
,
false
=>
{
panic!
(
"double free at index {:?}"
,
self
.0
)
}
ref
mut
d
=>
*
d
=
false
}
self
.1
.cur_ops
.set
(
self
.1
.cur_ops
.get
()
+
1
);
self
.1
.cur_ops
.set
(
self
.1
.cur_ops
.get
()
+
1
);
if
self
.1
.cur_ops
.get
()
==
self
.1
.failing_op
{
panic
::
panic_any
(
InjectedFailure
);
...
...
@@ -162,7 +177,11 @@ fn generator(a: &Allocator, run_count: usize) {
assert
!
(
run_count
<
4
);
let
mut
gen
=
||
{
(
a
.alloc
(),
yield
a
.alloc
(),
a
.alloc
(),
yield
a
.alloc
());
(
a
.alloc
(),
yield
a
.alloc
(),
a
.alloc
(),
yield
a
.alloc
()
);
};
for
_
in
0
..
run_count
{
Pin
::
new
(
&
mut
gen
)
.resume
(());
...
...
@@ -186,40 +205,28 @@ fn vec_unreachable(a: &Allocator) {
}
fn
slice_pattern_first
(
a
:
&
Allocator
)
{
let
[
_
x
,
..
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
[
_
x
,
..
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_middle
(
a
:
&
Allocator
)
{
let
[
_
,
_
x
,
_
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
[
_
,
_
x
,
_
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_two
(
a
:
&
Allocator
)
{
let
[
_
x
,
_
,
_
y
,
_
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
[
_
x
,
_
,
_
y
,
_
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_last
(
a
:
&
Allocator
)
{
let
[
..
,
_
y
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
[
..
,
_
y
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_one_of
(
a
:
&
Allocator
,
i
:
usize
)
{
let
array
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
_
x
=
match
i
{
0
=>
{
let
[
a
,
..
]
=
array
;
a
}
1
=>
{
let
[
_
,
a
,
..
]
=
array
;
a
}
2
=>
{
let
[
_
,
_
,
a
,
_
]
=
array
;
a
}
3
=>
{
let
[
_
,
_
,
_
,
a
]
=
array
;
a
}
0
=>
{
let
[
a
,
..
]
=
array
;
a
}
1
=>
{
let
[
_
,
a
,
..
]
=
array
;
a
}
2
=>
{
let
[
_
,
_
,
a
,
_
]
=
array
;
a
}
3
=>
{
let
[
_
,
_
,
_
,
a
]
=
array
;
a
}
_
=>
panic!
(
"unmatched"
),
};
}
...
...
@@ -227,9 +234,9 @@ fn slice_pattern_one_of(a: &Allocator, i: usize) {
fn
subslice_pattern_from_end
(
a
:
&
Allocator
,
arg
:
bool
)
{
let
a
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
if
arg
{
let
[
..
,
_
x
,
_
]
=
a
;
let
[
..
,
_
x
,
_
]
=
a
;
}
else
{
let
[
_
,
_
y
@
..
]
=
a
;
let
[
_
,
_
y
@
..
]
=
a
;
}
}
...
...
@@ -241,61 +248,45 @@ fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) {
}
if
arg
{
let
[
..
,
_
x
,
_
]
=
a
;
let
[
..
,
_
x
,
_
]
=
a
;
}
else
{
let
[
_
,
_
y
@
..
]
=
a
;
let
[
_
,
_
y
@
..
]
=
a
;
}
}
fn
slice_pattern_reassign
(
a
:
&
Allocator
)
{
let
mut
ar
=
[
a
.alloc
(),
a
.alloc
()];
let
[
_
,
_
x
]
=
ar
;
let
[
_
,
_
x
]
=
ar
;
ar
=
[
a
.alloc
(),
a
.alloc
()];
let
[
..
,
_
y
]
=
ar
;
let
[
..
,
_
y
]
=
ar
;
}
fn
subslice_pattern_reassign
(
a
:
&
Allocator
)
{
let
mut
ar
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
[
_
,
_
,
_
x
]
=
ar
;
let
[
_
,
_
,
_
x
]
=
ar
;
ar
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
[
_
,
_
y
@
..
]
=
ar
;
let
[
_
,
_
y
@
..
]
=
ar
;
}
fn
index_field_mixed_ends
(
a
:
&
Allocator
)
{
let
ar
=
[(
a
.alloc
(),
a
.alloc
()),
(
a
.alloc
(),
a
.alloc
())];
let
[(
_
x
,
_
),
..
]
=
ar
;
let
[(
_
,
_
y
),
_
]
=
ar
;
let
[
_
,
(
_
,
_
w
)]
=
ar
;
let
[
..
,
(
_
z
,
_
)]
=
ar
;
let
[(
_
x
,
_
),
..
]
=
ar
;
let
[(
_
,
_
y
),
_
]
=
ar
;
let
[
_
,
(
_
,
_
w
)]
=
ar
;
let
[
..
,
(
_
z
,
_
)]
=
ar
;
}
fn
subslice_mixed_min_lengths
(
a
:
&
Allocator
,
c
:
i32
)
{
let
ar
=
[(
a
.alloc
(),
a
.alloc
()),
(
a
.alloc
(),
a
.alloc
())];
match
c
{
0
=>
{
let
[
_
x
,
..
]
=
ar
;
}
1
=>
{
let
[
_
x
,
_
,
..
]
=
ar
;
}
2
=>
{
let
[
_
x
,
_
]
=
ar
;
}
3
=>
{
let
[(
_
x
,
_
),
_
,
..
]
=
ar
;
}
4
=>
{
let
[
..
,
(
_
x
,
_
)]
=
ar
;
}
5
=>
{
let
[
..
,
(
_
x
,
_
),
_
]
=
ar
;
}
6
=>
{
let
[
_
y
@
..
]
=
ar
;
}
_
=>
{
let
[
_
y
@
..
,
_
]
=
ar
;
}
0
=>
{
let
[
_
x
,
..
]
=
ar
;
}
1
=>
{
let
[
_
x
,
_
,
..
]
=
ar
;
}
2
=>
{
let
[
_
x
,
_
]
=
ar
;
}
3
=>
{
let
[(
_
x
,
_
),
_
,
..
]
=
ar
;
}
4
=>
{
let
[
..
,
(
_
x
,
_
)]
=
ar
;
}
5
=>
{
let
[
..
,
(
_
x
,
_
),
_
]
=
ar
;
}
6
=>
{
let
[
_
y
@
..
]
=
ar
;
}
_
=>
{
let
[
_
y
@
..
,
_
]
=
ar
;
}
}
}
...
...
@@ -343,160 +334,87 @@ fn move_ref_pattern(a: &Allocator) {
}
fn
panic_after_return
(
a
:
&
Allocator
)
->
Ptr
<
'_
>
{
// Panic in the drop of `p` or `q` can leak
let
exceptions
=
vec!
[
8
,
9
];
a
.alloc
();
let
p
=
a
.alloc
();
{
a
.alloc
();
let
p
=
a
.alloc
();
a
.alloc
()
// FIXME (#47949) We leak values when we panic in a destructor after
// evaluating an expression with `rustc_mir::build::Builder::into`.
a
.alloc_leaked
(
exceptions
)
}
}
fn
panic_after_return_expr
(
a
:
&
Allocator
)
->
Ptr
<
'_
>
{
// Panic in the drop of `p` or `q` can leak
let
exceptions
=
vec!
[
8
,
9
];
a
.alloc
();
let
p
=
a
.alloc
();
{
a
.alloc
();
let
q
=
a
.alloc
();
return
a
.alloc
();
// FIXME (#47949)
return
a
.alloc_leaked
(
exceptions
);
}
}
fn
panic_after_init
(
a
:
&
Allocator
)
{
// Panic in the drop of `r` can leak
let
exceptions
=
vec!
[
8
];
a
.alloc
();
let
p
=
a
.alloc
();
let
q
=
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
// FIXME (#47949)
a
.alloc_leaked
(
exceptions
)
};
}
fn
panic_after_init_temp
(
a
:
&
Allocator
)
{
// Panic in the drop of `r` can leak
let
exceptions
=
vec!
[
8
];
a
.alloc
();
let
p
=
a
.alloc
();
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
// FIXME (#47949)
a
.alloc_leaked
(
exceptions
)
};
}
fn
panic_after_init_by_loop
(
a
:
&
Allocator
)
{
// Panic in the drop of `r` can leak
let
exceptions
=
vec!
[
8
];
a
.alloc
();
let
p
=
a
.alloc
();
let
q
=
loop
{
a
.alloc
();
let
r
=
a
.alloc
();
break
a
.alloc
();
};
}
fn
panic_after_init_by_match
(
a
:
&
Allocator
,
b
:
bool
)
{
a
.alloc
();
let
p
=
a
.alloc
();
let
_
=
loop
{
let
q
=
match
b
{
true
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
}
false
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
break
a
.alloc
();
}
};
return
;
};
}
fn
panic_after_init_by_match_with_guard
(
a
:
&
Allocator
,
b
:
bool
)
{
a
.alloc
();
let
p
=
a
.alloc
();
let
q
=
match
a
.alloc
()
{
_
if
b
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
}
_
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
}
};
}
fn
panic_after_init_by_match_with_bindings_and_guard
(
a
:
&
Allocator
,
b
:
bool
)
{
a
.alloc
();
let
p
=
a
.alloc
();
let
q
=
match
a
.alloc
()
{
_
x
if
b
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
}
_
x
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
}
};
}
fn
panic_after_init_by_match_with_ref_bindings_and_guard
(
a
:
&
Allocator
,
b
:
bool
)
{
a
.alloc
();
let
p
=
a
.alloc
();
let
q
=
match
a
.alloc
()
{
ref
_
x
if
b
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
}
ref
_
x
=>
{
a
.alloc
();
let
r
=
a
.alloc
();
a
.alloc
()
}
};
}
fn
panic_after_init_by_break_if
(
a
:
&
Allocator
,
b
:
bool
)
{
a
.alloc
();
let
p
=
a
.alloc
();
let
q
=
loop
{
let
r
=
a
.alloc
();
break
if
b
{
let
s
=
a
.alloc
();
a
.alloc
()
}
else
{
a
.alloc
()
};
// FIXME (#47949)
break
a
.alloc_leaked
(
exceptions
);
};
}
fn
run_test
<
F
>
(
mut
f
:
F
,
name
:
&
'static
str
)
where
F
:
FnMut
(
&
Allocator
),
fn
run_test
<
F
>
(
mut
f
:
F
)
where
F
:
FnMut
(
&
Allocator
)
{
let
first_alloc
=
Allocator
::
new
(
usize
::
MAX
,
name
);
let
first_alloc
=
Allocator
::
new
(
usize
::
MAX
);
f
(
&
first_alloc
);
for
failing_op
in
1
..
first_alloc
.cur_ops
.get
()
+
1
{
let
alloc
=
Allocator
::
new
(
failing_op
,
name
);
for
failing_op
in
1
..
first_alloc
.cur_ops
.get
()
+
1
{
let
alloc
=
Allocator
::
new
(
failing_op
);
let
alloc
=
&
alloc
;
let
f
=
panic
::
AssertUnwindSafe
(
&
mut
f
);
let
result
=
panic
::
catch_unwind
(
move
||
{
f
.0
(
alloc
);
});
match
result
{
Ok
(
..
)
=>
panic!
(
"test executed {} ops but now {}"
,
first_alloc
.cur_ops
.get
(),
alloc
.cur_ops
.get
()
),
Ok
(
..
)
=>
panic!
(
"test executed {} ops but now {}"
,
first_alloc
.cur_ops
.get
(),
alloc
.cur_ops
.get
()),
Err
(
e
)
=>
{
if
e
.downcast_ref
::
<
InjectedFailure
>
()
.is_none
()
{
panic
::
resume_unwind
(
e
);
...
...
@@ -506,115 +424,98 @@ fn run_test<F>(mut f: F, name: &'static str)
}
}
fn
run_test_nopanic
<
F
>
(
mut
f
:
F
,
name
:
&
'static
str
)
where
F
:
FnMut
(
&
Allocator
),
fn
run_test_nopanic
<
F
>
(
mut
f
:
F
)
where
F
:
FnMut
(
&
Allocator
)
{
let
first_alloc
=
Allocator
::
new
(
usize
::
MAX
,
name
);
let
first_alloc
=
Allocator
::
new
(
usize
::
MAX
);
f
(
&
first_alloc
);
}
macro_rules!
run_test
{
(
$e:expr
)
=>
{
run_test
(
$e
,
stringify!
(
$e
));
};
}
fn
main
()
{
run_test
!
(|
a
|
dynamic_init
(
a
,
false
));
run_test
!
(|
a
|
dynamic_init
(
a
,
true
));
run_test
!
(|
a
|
dynamic_drop
(
a
,
false
));
run_test
!
(|
a
|
dynamic_drop
(
a
,
true
));
run_test
!
(|
a
|
assignment2
(
a
,
false
,
false
));
run_test
!
(|
a
|
assignment2
(
a
,
false
,
true
));
run_test
!
(|
a
|
assignment2
(
a
,
true
,
false
));
run_test
!
(|
a
|
assignment2
(
a
,
true
,
true
));
run_test
!
(|
a
|
assignment1
(
a
,
false
));
run_test
!
(|
a
|
assignment1
(
a
,
true
));
run_test
!
(|
a
|
array_simple
(
a
));
run_test
!
(|
a
|
vec_simple
(
a
));
run_test
!
(|
a
|
vec_unreachable
(
a
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
false
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
true
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
false
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
true
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
false
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
true
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
false
));
run_test
!
(|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
true
));
run_test
!
(|
a
|
field_assignment
(
a
,
false
));
run_test
!
(|
a
|
field_assignment
(
a
,
true
));
run_test
!
(|
a
|
generator
(
a
,
0
));
run_test
!
(|
a
|
generator
(
a
,
1
));
run_test
!
(|
a
|
generator
(
a
,
2
));
run_test
!
(|
a
|
generator
(
a
,
3
));
run_test
!
(|
a
|
mixed_drop_and_nondrop
(
a
));
run_test
!
(|
a
|
slice_pattern_first
(
a
));
run_test
!
(|
a
|
slice_pattern_middle
(
a
));
run_test
!
(|
a
|
slice_pattern_two
(
a
));
run_test
!
(|
a
|
slice_pattern_last
(
a
));
run_test
!
(|
a
|
slice_pattern_one_of
(
a
,
0
));
run_test
!
(|
a
|
slice_pattern_one_of
(
a
,
1
));
run_test
!
(|
a
|
slice_pattern_one_of
(
a
,
2
));
run_test
!
(|
a
|
slice_pattern_one_of
(
a
,
3
));
run_test
!
(|
a
|
subslice_pattern_from_end
(
a
,
true
));
run_test
!
(|
a
|
subslice_pattern_from_end
(
a
,
false
));
run_test
!
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
true
));
run_test
!
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
false
));
run_test
!
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
true
));
run_test
!
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
false
));
run_test
!
(|
a
|
slice_pattern_reassign
(
a
));
run_test
!
(|
a
|
subslice_pattern_reassign
(
a
));
run_test
!
(|
a
|
index_field_mixed_ends
(
a
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
0
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
1
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
2
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
3
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
4
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
5
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
6
));
run_test
!
(|
a
|
subslice_mixed_min_lengths
(
a
,
7
));
run_test
!
(|
a
|
move_ref_pattern
(
a
));
run_test
!
(|
a
|
{
run_test
(|
a
|
dynamic_init
(
a
,
false
));
run_test
(|
a
|
dynamic_init
(
a
,
true
));
run_test
(|
a
|
dynamic_drop
(
a
,
false
));
run_test
(|
a
|
dynamic_drop
(
a
,
true
));
run_test
(|
a
|
assignment2
(
a
,
false
,
false
));
run_test
(|
a
|
assignment2
(
a
,
false
,
true
));
run_test
(|
a
|
assignment2
(
a
,
true
,
false
));
run_test
(|
a
|
assignment2
(
a
,
true
,
true
));
run_test
(|
a
|
assignment1
(
a
,
false
));
run_test
(|
a
|
assignment1
(
a
,
true
));
run_test
(|
a
|
array_simple
(
a
));
run_test
(|
a
|
vec_simple
(
a
));
run_test
(|
a
|
vec_unreachable
(
a
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
false
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
false
,
false
,
true
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
false
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
false
,
true
,
true
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
false
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
true
,
false
,
true
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
false
));
run_test
(|
a
|
struct_dynamic_drop
(
a
,
true
,
true
,
true
));
run_test
(|
a
|
field_assignment
(
a
,
false
));
run_test
(|
a
|
field_assignment
(
a
,
true
));
run_test
(|
a
|
generator
(
a
,
0
));
run_test
(|
a
|
generator
(
a
,
1
));
run_test
(|
a
|
generator
(
a
,
2
));
run_test
(|
a
|
generator
(
a
,
3
));
run_test
(|
a
|
mixed_drop_and_nondrop
(
a
));
run_test
(|
a
|
slice_pattern_first
(
a
));
run_test
(|
a
|
slice_pattern_middle
(
a
));
run_test
(|
a
|
slice_pattern_two
(
a
));
run_test
(|
a
|
slice_pattern_last
(
a
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
0
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
1
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
2
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
3
));
run_test
(|
a
|
subslice_pattern_from_end
(
a
,
true
));
run_test
(|
a
|
subslice_pattern_from_end
(
a
,
false
));
run_test
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
true
));
run_test
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
true
,
false
));
run_test
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
true
));
run_test
(|
a
|
subslice_pattern_from_end_with_drop
(
a
,
false
,
false
));
run_test
(|
a
|
slice_pattern_reassign
(
a
));
run_test
(|
a
|
subslice_pattern_reassign
(
a
));
run_test
(|
a
|
index_field_mixed_ends
(
a
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
0
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
1
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
2
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
3
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
4
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
5
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
6
));
run_test
(|
a
|
subslice_mixed_min_lengths
(
a
,
7
));
run_test
(|
a
|
move_ref_pattern
(
a
));
run_test
(|
a
|
{
panic_after_return
(
a
);
});
run_test
!
(|
a
|
{
run_test
(|
a
|
{
panic_after_return_expr
(
a
);
});
run_test!
(|
a
|
panic_after_init
(
a
));
run_test!
(|
a
|
panic_after_init_temp
(
a
));
run_test!
(|
a
|
panic_after_init_by_loop
(
a
));
run_test!
(|
a
|
panic_after_init_by_match
(
a
,
false
));
run_test!
(|
a
|
panic_after_init_by_match
(
a
,
true
));
run_test!
(|
a
|
panic_after_init_by_match_with_guard
(
a
,
false
));
run_test!
(|
a
|
panic_after_init_by_match_with_guard
(
a
,
true
));
run_test!
(|
a
|
panic_after_init_by_match_with_bindings_and_guard
(
a
,
false
));
run_test!
(|
a
|
panic_after_init_by_match_with_bindings_and_guard
(
a
,
true
));
run_test!
(|
a
|
panic_after_init_by_match_with_ref_bindings_and_guard
(
a
,
false
));
run_test!
(|
a
|
panic_after_init_by_match_with_ref_bindings_and_guard
(
a
,
true
));
run_test!
(|
a
|
panic_after_init_by_break_if
(
a
,
false
));
run_test!
(|
a
|
panic_after_init_by_break_if
(
a
,
true
));
run_test!
(|
a
|
bindings_after_at_dynamic_init_move
(
a
,
true
));
run_test!
(|
a
|
bindings_after_at_dynamic_init_move
(
a
,
false
));
run_test!
(|
a
|
bindings_after_at_dynamic_init_ref
(
a
,
true
));
run_test!
(|
a
|
bindings_after_at_dynamic_init_ref
(
a
,
false
));
run_test!
(|
a
|
bindings_after_at_dynamic_drop_move
(
a
,
true
));
run_test!
(|
a
|
bindings_after_at_dynamic_drop_move
(
a
,
false
));
run_test!
(|
a
|
bindings_after_at_dynamic_drop_ref
(
a
,
true
));
run_test!
(|
a
|
bindings_after_at_dynamic_drop_ref
(
a
,
false
));
run_test_nopanic
(|
a
|
union1
(
a
),
"|a| union1(a)"
);
run_test
(|
a
|
panic_after_init
(
a
));
run_test
(|
a
|
panic_after_init_temp
(
a
));
run_test
(|
a
|
panic_after_init_by_loop
(
a
));
run_test
(|
a
|
bindings_after_at_dynamic_init_move
(
a
,
true
));
run_test
(|
a
|
bindings_after_at_dynamic_init_move
(
a
,
false
));
run_test
(|
a
|
bindings_after_at_dynamic_init_ref
(
a
,
true
));
run_test
(|
a
|
bindings_after_at_dynamic_init_ref
(
a
,
false
));
run_test
(|
a
|
bindings_after_at_dynamic_drop_move
(
a
,
true
));
run_test
(|
a
|
bindings_after_at_dynamic_drop_move
(
a
,
false
));
run_test
(|
a
|
bindings_after_at_dynamic_drop_ref
(
a
,
true
));
run_test
(|
a
|
bindings_after_at_dynamic_drop_ref
(
a
,
false
));
run_test_nopanic
(|
a
|
union1
(
a
));
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录