Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
0d0d2fe1
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
0d0d2fe1
编写于
9月 08, 2021
作者:
B
bors
浏览文件
操作
浏览文件
下载
差异文件
Auto merge of #88477 - sexxi-goose:issue-88476, r=nikomatsakis
2229: Don't move out of drop type Fixes #88476 r? `@nikomatsakis`
上级
fdf65053
153aa71c
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
239 addition
and
1 deletion
+239
-1
compiler/rustc_typeck/src/check/upvar.rs
compiler/rustc_typeck/src/check/upvar.rs
+33
-1
src/test/ui/closures/2229_closure_analysis/issue-88476.rs
src/test/ui/closures/2229_closure_analysis/issue-88476.rs
+62
-0
src/test/ui/closures/2229_closure_analysis/issue-88476.stderr
...test/ui/closures/2229_closure_analysis/issue-88476.stderr
+97
-0
src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs
...ui/closures/2229_closure_analysis/run_pass/issue-88476.rs
+47
-0
未找到文件。
compiler/rustc_typeck/src/check/upvar.rs
浏览文件 @
0d0d2fe1
...
...
@@ -399,7 +399,14 @@ fn process_collected_capture_information(
}
};
// This restriction needs to be applied after we have handled adjustments for `move`
// closures. We want to make sure any adjustment that might make us move the place into
// the closure gets handled.
let
(
place
,
capture_kind
)
=
restrict_precision_for_drop_types
(
self
,
place
,
capture_kind
,
usage_span
);
capture_info
.capture_kind
=
capture_kind
;
let
capture_info
=
if
let
Some
(
existing
)
=
processed
.get
(
&
place
)
{
determine_capture_info
(
*
existing
,
capture_info
)
}
else
{
...
...
@@ -1852,6 +1859,31 @@ fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::H
self
.borrow
(
assignee_place
,
diag_expr_id
,
ty
::
BorrowKind
::
MutBorrow
);
}
}
/// Rust doesn't permit moving fields out of a type that implements drop
fn
restrict_precision_for_drop_types
<
'a
,
'tcx
>
(
fcx
:
&
'a
FnCtxt
<
'a
,
'tcx
>
,
mut
place
:
Place
<
'tcx
>
,
mut
curr_mode
:
ty
::
UpvarCapture
<
'tcx
>
,
span
:
Span
,
)
->
(
Place
<
'tcx
>
,
ty
::
UpvarCapture
<
'tcx
>
)
{
let
is_copy_type
=
fcx
.infcx
.type_is_copy_modulo_regions
(
fcx
.param_env
,
place
.ty
(),
span
);
if
let
(
false
,
UpvarCapture
::
ByValue
(
..
))
=
(
is_copy_type
,
curr_mode
)
{
for
i
in
0
..
place
.projections
.len
()
{
match
place
.ty_before_projection
(
i
)
.kind
()
{
ty
::
Adt
(
def
,
_
)
if
def
.destructor
(
fcx
.tcx
)
.is_some
()
=>
{
truncate_place_to_len_and_update_capture_kind
(
&
mut
place
,
&
mut
curr_mode
,
i
);
break
;
}
_
=>
{}
}
}
}
(
place
,
curr_mode
)
}
/// Truncate `place` so that an `unsafe` block isn't required to capture it.
/// - No projections are applied to raw pointers, since these require unsafe blocks. We capture
/// them completely.
...
...
src/test/ui/closures/2229_closure_analysis/issue-88476.rs
0 → 100644
浏览文件 @
0d0d2fe1
// edition:2021
#![feature(rustc_attrs)]
// Test that we can't move out of struct that impls `Drop`.
use
std
::
rc
::
Rc
;
// Test that we restrict precision when moving not-`Copy` types, if any of the parent paths
// implement `Drop`. This is to ensure that we don't move out of a type that implements Drop.
pub
fn
test1
()
{
struct
Foo
(
Rc
<
i32
>
);
impl
Drop
for
Foo
{
fn
drop
(
self
:
&
mut
Foo
)
{}
}
let
f
=
Foo
(
Rc
::
new
(
1
));
let
x
=
#[rustc_capture_analysis]
move
||
{
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
//~| ERROR: First Pass analysis includes:
//~| ERROR: Min Capture analysis includes:
println!
(
"{:?}"
,
f
.0
);
//~^ NOTE: Capturing f[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture f[] -> ByValue
};
x
();
}
// Test that we don't restrict precision when moving `Copy` types(i.e. when copying),
// even if any of the parent paths implement `Drop`.
fn
test2
()
{
struct
Character
{
hp
:
u32
,
name
:
String
,
}
impl
Drop
for
Character
{
fn
drop
(
&
mut
self
)
{}
}
let
character
=
Character
{
hp
:
100
,
name
:
format!
(
"A"
)
};
let
c
=
#[rustc_capture_analysis]
move
||
{
//~^ ERROR: attributes on expressions are experimental
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
//~| ERROR: First Pass analysis includes:
//~| ERROR: Min Capture analysis includes:
println!
(
"{}"
,
character
.hp
)
//~^ NOTE: Capturing character[(0, 0)] -> ImmBorrow
//~| NOTE: Min Capture character[(0, 0)] -> ByValue
};
c
();
println!
(
"{}"
,
character
.name
);
}
fn
main
()
{}
src/test/ui/closures/2229_closure_analysis/issue-88476.stderr
0 → 100644
浏览文件 @
0d0d2fe1
error[E0658]: attributes on expressions are experimental
--> $DIR/issue-88476.rs:20:13
|
LL | let x = #[rustc_capture_analysis] move || {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error[E0658]: attributes on expressions are experimental
--> $DIR/issue-88476.rs:47:13
|
LL | let c = #[rustc_capture_analysis] move || {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
error: First Pass analysis includes:
--> $DIR/issue-88476.rs:20:39
|
LL | let x = #[rustc_capture_analysis] move || {
| _______________________________________^
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_____^
|
note: Capturing f[(0, 0)] -> ImmBorrow
--> $DIR/issue-88476.rs:25:26
|
LL | println!("{:?}", f.0);
| ^^^
error: Min Capture analysis includes:
--> $DIR/issue-88476.rs:20:39
|
LL | let x = #[rustc_capture_analysis] move || {
| _______________________________________^
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_____^
|
note: Min Capture f[] -> ByValue
--> $DIR/issue-88476.rs:25:26
|
LL | println!("{:?}", f.0);
| ^^^
error: First Pass analysis includes:
--> $DIR/issue-88476.rs:47:39
|
LL | let c = #[rustc_capture_analysis] move || {
| _______________________________________^
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_____^
|
note: Capturing character[(0, 0)] -> ImmBorrow
--> $DIR/issue-88476.rs:52:24
|
LL | println!("{}", character.hp)
| ^^^^^^^^^^^^
error: Min Capture analysis includes:
--> $DIR/issue-88476.rs:47:39
|
LL | let c = #[rustc_capture_analysis] move || {
| _______________________________________^
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_____^
|
note: Min Capture character[(0, 0)] -> ByValue
--> $DIR/issue-88476.rs:52:24
|
LL | println!("{}", character.hp)
| ^^^^^^^^^^^^
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0658`.
src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs
0 → 100644
浏览文件 @
0d0d2fe1
// check-pass
// edition:2021
use
std
::
rc
::
Rc
;
// Test that we restrict precision when moving not-`Copy` types, if any of the parent paths
// implement `Drop`. This is to ensure that we don't move out of a type that implements Drop.
pub
fn
test1
()
{
struct
Foo
(
Rc
<
i32
>
);
impl
Drop
for
Foo
{
fn
drop
(
self
:
&
mut
Foo
)
{}
}
let
f
=
Foo
(
Rc
::
new
(
1
));
let
x
=
move
||
{
println!
(
"{:?}"
,
f
.0
);
};
x
();
}
// Test that we don't restrict precision when moving `Copy` types(i.e. when copying),
// even if any of the parent paths implement `Drop`.
pub
fn
test2
()
{
struct
Character
{
hp
:
u32
,
name
:
String
,
}
impl
Drop
for
Character
{
fn
drop
(
&
mut
self
)
{}
}
let
character
=
Character
{
hp
:
100
,
name
:
format!
(
"A"
)
};
let
c
=
move
||
{
println!
(
"{}"
,
character
.hp
)
};
c
();
println!
(
"{}"
,
character
.name
);
}
fn
main
()
{}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录