Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
7119974f
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,发现更多精彩内容 >>
提交
7119974f
编写于
9月 20, 2014
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move unsafe destructor check from kind.rs into wf.rs
上级
c31623b0
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
78 addition
and
83 deletion
+78
-83
src/librustc/diagnostics.rs
src/librustc/diagnostics.rs
+0
-1
src/librustc/middle/kind.rs
src/librustc/middle/kind.rs
+0
-81
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/mod.rs
+3
-0
src/librustc/middle/typeck/check/vtable2.rs
src/librustc/middle/typeck/check/vtable2.rs
+8
-0
src/librustc/middle/typeck/check/wf.rs
src/librustc/middle/typeck/check/wf.rs
+46
-0
src/test/compile-fail/kindck-destructor-owned.rs
src/test/compile-fail/kindck-destructor-owned.rs
+21
-1
未找到文件。
src/librustc/diagnostics.rs
浏览文件 @
7119974f
...
...
@@ -130,7 +130,6 @@
E0121
,
E0122
,
E0124
,
E0125
,
E0126
,
E0127
,
E0128
,
...
...
src/librustc/middle/kind.rs
浏览文件 @
7119974f
...
...
@@ -9,15 +9,11 @@
// except according to those terms.
use
middle
::
mem_categorization
::
Typer
;
use
middle
::
subst
;
use
middle
::
ty
;
use
middle
::
ty_fold
::
TypeFoldable
;
use
middle
::
ty_fold
;
use
util
::
ppaux
::{
ty_to_string
};
use
util
::
ppaux
::
UserString
;
use
syntax
::
ast
::
*
;
use
syntax
::
attr
;
use
syntax
::
codemap
::
Span
;
use
syntax
::
print
::
pprust
::{
expr_to_string
,
ident_to_string
};
use
syntax
::
visit
::
Visitor
;
...
...
@@ -48,10 +44,6 @@ fn visit_ty(&mut self, t: &Ty) {
check_ty
(
self
,
t
);
}
fn
visit_item
(
&
mut
self
,
i
:
&
Item
)
{
check_item
(
self
,
i
);
}
fn
visit_pat
(
&
mut
self
,
p
:
&
Pat
)
{
check_pat
(
self
,
p
);
}
...
...
@@ -65,79 +57,6 @@ pub fn check_crate(tcx: &ty::ctxt) {
tcx
.sess
.abort_if_errors
();
}
struct
EmptySubstsFolder
<
'a
,
'tcx
:
'a
>
{
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
}
impl
<
'a
,
'tcx
>
ty_fold
::
TypeFolder
<
'tcx
>
for
EmptySubstsFolder
<
'a
,
'tcx
>
{
fn
tcx
<
'a
>
(
&
'a
self
)
->
&
'a
ty
::
ctxt
<
'tcx
>
{
self
.tcx
}
fn
fold_substs
(
&
mut
self
,
_
:
&
subst
::
Substs
)
->
subst
::
Substs
{
subst
::
Substs
::
empty
()
}
}
fn
check_struct_safe_for_destructor
(
cx
:
&
mut
Context
,
span
:
Span
,
struct_did
:
DefId
)
{
let
struct_tpt
=
ty
::
lookup_item_type
(
cx
.tcx
,
struct_did
);
if
!
struct_tpt
.generics
.has_type_params
(
subst
::
TypeSpace
)
&&
!
struct_tpt
.generics
.has_region_params
(
subst
::
TypeSpace
)
{
let
mut
folder
=
EmptySubstsFolder
{
tcx
:
cx
.tcx
};
if
!
ty
::
type_is_sendable
(
cx
.tcx
,
struct_tpt
.ty
.fold_with
(
&
mut
folder
))
{
span_err!
(
cx
.tcx.sess
,
span
,
E0125
,
"cannot implement a destructor on a
\
structure or enumeration that does not satisfy Send"
);
span_note!
(
cx
.tcx.sess
,
span
,
"use
\"
#[unsafe_destructor]
\"
on the implementation
\
to force the compiler to allow this"
);
}
}
else
{
span_err!
(
cx
.tcx.sess
,
span
,
E0141
,
"cannot implement a destructor on a structure
\
with type parameters"
);
span_note!
(
cx
.tcx.sess
,
span
,
"use
\"
#[unsafe_destructor]
\"
on the implementation
\
to force the compiler to allow this"
);
}
}
fn
check_impl_of_trait
(
cx
:
&
mut
Context
,
it
:
&
Item
,
trait_ref
:
&
TraitRef
,
self_type
:
&
Ty
)
{
let
ast_trait_def
=
*
cx
.tcx.def_map
.borrow
()
.find
(
&
trait_ref
.ref_id
)
.expect
(
"trait ref not in def map!"
);
let
trait_def_id
=
ast_trait_def
.def_id
();
// If this is a destructor, check kinds.
if
cx
.tcx.lang_items
.drop_trait
()
==
Some
(
trait_def_id
)
&&
!
attr
::
contains_name
(
it
.attrs
.as_slice
(),
"unsafe_destructor"
)
{
match
self_type
.node
{
TyPath
(
_
,
ref
bounds
,
path_node_id
)
=>
{
assert
!
(
bounds
.is_none
());
let
struct_def
=
cx
.tcx.def_map
.borrow
()
.get_copy
(
&
path_node_id
);
let
struct_did
=
struct_def
.def_id
();
check_struct_safe_for_destructor
(
cx
,
self_type
.span
,
struct_did
);
}
_
=>
{
cx
.tcx.sess
.span_bug
(
self_type
.span
,
"the self type for the Drop trait impl is not a path"
);
}
}
}
}
fn
check_item
(
cx
:
&
mut
Context
,
item
:
&
Item
)
{
match
item
.node
{
ItemImpl
(
_
,
Some
(
ref
trait_ref
),
ref
self_type
,
_
)
=>
{
check_impl_of_trait
(
cx
,
item
,
trait_ref
,
&**
self_type
);
}
_
=>
{}
}
visit
::
walk_item
(
cx
,
item
)
}
// Yields the appropriate function to check the kind of closed over
// variables. `id` is the NodeId for some expression that creates the
// closure.
...
...
src/librustc/middle/traits/mod.rs
浏览文件 @
7119974f
...
...
@@ -69,6 +69,9 @@ pub enum ObligationCauseCode {
/// Obligation incurred due to an object cast.
ObjectCastObligation
(
/* Object type */
ty
::
t
),
/// To implement drop, type must be sendable.
DropTrait
,
/// Various cases where expressions must be sized/copy/etc:
AssignmentLhsSized
,
// L = X implies that L is Sized
StructInitializerSized
,
// S { ... } must be Sized
...
...
src/librustc/middle/typeck/check/vtable2.rs
浏览文件 @
7119974f
...
...
@@ -390,5 +390,13 @@ fn note_obligation_cause(fcx: &FnCtxt,
obligation
.cause.span
,
"structs must have a statically known size to be initialized"
);
}
traits
::
DropTrait
=>
{
span_note!
(
tcx
.sess
,
obligation
.cause.span
,
"cannot implement a destructor on a
\
structure or enumeration that does not satisfy Send"
);
span_note!
(
tcx
.sess
,
obligation
.cause.span
,
"use
\"
#[unsafe_destructor]
\"
on the implementation
\
to force the compiler to allow this"
);
}
}
}
src/librustc/middle/typeck/check/wf.rs
浏览文件 @
7119974f
...
...
@@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
middle
::
subst
;
use
middle
::
subst
::{
Subst
};
use
middle
::
traits
;
use
middle
::
ty
;
...
...
@@ -21,6 +22,7 @@
use
std
::
collections
::
HashSet
;
use
syntax
::
ast
;
use
syntax
::
ast_util
::{
local_def
};
use
syntax
::
attr
;
use
syntax
::
codemap
::
Span
;
use
syntax
::
visit
;
use
syntax
::
visit
::
Visitor
;
...
...
@@ -165,6 +167,22 @@ fn check_impl(&mut self,
};
let
trait_ref
=
(
*
trait_ref
)
.subst
(
fcx
.tcx
(),
&
fcx
.inh.param_env.free_substs
);
// There are special rules that apply to drop.
if
fcx
.tcx
()
.lang_items
.drop_trait
()
==
Some
(
trait_ref
.def_id
)
&&
!
attr
::
contains_name
(
item
.attrs
.as_slice
(),
"unsafe_destructor"
)
{
match
ty
::
get
(
self_ty
)
.sty
{
ty
::
ty_struct
(
def_id
,
_
)
|
ty
::
ty_enum
(
def_id
,
_
)
=>
{
check_struct_safe_for_destructor
(
fcx
,
item
.span
,
self_ty
,
def_id
);
}
_
=>
{
// Coherence already reports an error in this case.
}
}
}
// We are stricter on the trait-ref in an impl than the
// self-type. In particular, we enforce region
// relationships. The reason for this is that (at least
...
...
@@ -362,3 +380,31 @@ fn fold_ty(&mut self, t: ty::t) -> ty::t {
t
// we're not folding to produce a new type, so just return `t` here
}
}
///////////////////////////////////////////////////////////////////////////
// Special drop trait checking
fn
check_struct_safe_for_destructor
(
fcx
:
&
FnCtxt
,
span
:
Span
,
self_ty
:
ty
::
t
,
struct_did
:
ast
::
DefId
)
{
let
struct_tpt
=
ty
::
lookup_item_type
(
fcx
.tcx
(),
struct_did
);
if
!
struct_tpt
.generics
.has_type_params
(
subst
::
TypeSpace
)
&&
!
struct_tpt
.generics
.has_region_params
(
subst
::
TypeSpace
)
{
let
cause
=
traits
::
ObligationCause
::
new
(
span
,
traits
::
DropTrait
);
fcx
.register_obligation
(
traits
::
obligation_for_builtin_bound
(
fcx
.tcx
(),
cause
,
self_ty
,
ty
::
BoundSend
));
}
else
{
span_err!
(
fcx
.tcx
()
.sess
,
span
,
E0141
,
"cannot implement a destructor on a structure
\
with type parameters"
);
span_note!
(
fcx
.tcx
()
.sess
,
span
,
"use
\"
#[unsafe_destructor]
\"
on the implementation
\
to force the compiler to allow this"
);
}
}
src/test/compile-fail/kindck-destructor-owned.rs
浏览文件 @
7119974f
...
...
@@ -16,7 +16,27 @@ struct Foo {
}
impl
Drop
for
Foo
{
//~^ ERROR cannot implement a destructor on a structure or enumeration that does not satisfy Send
//~^ ERROR the trait `core::kinds::Send` is not implemented for the type `Foo`
//~^^ NOTE cannot implement a destructor on a structure or enumeration that does not satisfy Send
fn
drop
(
&
mut
self
)
{
}
}
struct
Bar
<
'a
>
{
f
:
&
'a
int
,
}
impl
<
'a
>
Drop
for
Bar
<
'a
>
{
//~^ ERROR E0141
fn
drop
(
&
mut
self
)
{
}
}
struct
Baz
{
f
:
&
'static
int
,
}
impl
Drop
for
Baz
{
fn
drop
(
&
mut
self
)
{
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录