Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
62cb7510
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,发现更多精彩内容 >>
提交
62cb7510
编写于
8月 26, 2016
作者:
V
Vadim Petrochenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improve `Eq` deriving
上级
2a2c9d38
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
109 addition
and
36 deletion
+109
-36
src/libcore/cmp.rs
src/libcore/cmp.rs
+12
-1
src/libsyntax/ext/build.rs
src/libsyntax/ext/build.rs
+18
-0
src/libsyntax_ext/deriving/clone.rs
src/libsyntax_ext/deriving/clone.rs
+1
-14
src/libsyntax_ext/deriving/cmp/eq.rs
src/libsyntax_ext/deriving/cmp/eq.rs
+36
-19
src/test/compile-fail/union/union-derive-eq.rs
src/test/compile-fail/union/union-derive-eq.rs
+30
-0
src/test/compile-fail/union/union-derive.rs
src/test/compile-fail/union/union-derive.rs
+0
-1
src/test/run-pass/union/union-derive.rs
src/test/run-pass/union/union-derive.rs
+12
-1
未找到文件。
src/libcore/cmp.rs
浏览文件 @
62cb7510
...
...
@@ -129,7 +129,7 @@ fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
/// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
/// no extra methods, it is only informing the compiler that this is an
/// equivalence relation rather than a partial equivalence relation. Note that
/// the `derive` strategy requires all fields are `
Partial
Eq`, which isn't
/// the `derive` strategy requires all fields are `Eq`, which isn't
/// always desired.
///
/// ## How can I implement `Eq`?
...
...
@@ -165,6 +165,17 @@ pub trait Eq: PartialEq<Self> {
fn
assert_receiver_is_total_eq
(
&
self
)
{}
}
// FIXME: this struct is used solely by #[derive] to
// assert that every component of a type implements Eq.
//
// This struct should never appear in user code.
#[doc(hidden)]
#[allow(missing_debug_implementations)]
#[unstable(feature
=
"derive_eq"
,
reason
=
"deriving hack, should not be public"
,
issue
=
"0"
)]
pub
struct
AssertParamIsEq
<
T
:
Eq
+
?
Sized
>
{
_
field
:
::
marker
::
PhantomData
<
T
>
}
/// An `Ordering` is the result of a comparison between two values.
///
/// # Examples
...
...
src/libsyntax/ext/build.rs
浏览文件 @
62cb7510
...
...
@@ -97,6 +97,7 @@ fn stmt_let_typed(&self,
typ
:
P
<
ast
::
Ty
>
,
ex
:
P
<
ast
::
Expr
>
)
->
P
<
ast
::
Stmt
>
;
fn
stmt_let_type_only
(
&
self
,
span
:
Span
,
ty
:
P
<
ast
::
Ty
>
)
->
ast
::
Stmt
;
fn
stmt_item
(
&
self
,
sp
:
Span
,
item
:
P
<
ast
::
Item
>
)
->
ast
::
Stmt
;
// blocks
...
...
@@ -577,6 +578,23 @@ fn stmt_let_typed(&self,
})
}
// Generate `let _: Type;`, usually used for type assertions.
fn
stmt_let_type_only
(
&
self
,
span
:
Span
,
ty
:
P
<
ast
::
Ty
>
)
->
ast
::
Stmt
{
let
local
=
P
(
ast
::
Local
{
pat
:
self
.pat_wild
(
span
),
ty
:
Some
(
ty
),
init
:
None
,
id
:
ast
::
DUMMY_NODE_ID
,
span
:
span
,
attrs
:
ast
::
ThinVec
::
new
(),
});
ast
::
Stmt
{
id
:
ast
::
DUMMY_NODE_ID
,
node
:
ast
::
StmtKind
::
Local
(
local
),
span
:
span
,
}
}
fn
stmt_item
(
&
self
,
sp
:
Span
,
item
:
P
<
ast
::
Item
>
)
->
ast
::
Stmt
{
ast
::
Stmt
{
id
:
ast
::
DUMMY_NODE_ID
,
...
...
src/libsyntax_ext/deriving/clone.rs
浏览文件 @
62cb7510
...
...
@@ -115,20 +115,7 @@ fn assert_ty_bounds(cx: &mut ExtCtxt, stmts: &mut Vec<ast::Stmt>,
let
assert_path
=
cx
.path_all
(
span
,
true
,
cx
.std_path
(
&
[
"clone"
,
helper_name
]),
vec!
[],
vec!
[
ty
],
vec!
[]);
let
local
=
P
(
ast
::
Local
{
pat
:
cx
.pat_wild
(
span
),
ty
:
Some
(
cx
.ty_path
(
assert_path
)),
init
:
None
,
id
:
ast
::
DUMMY_NODE_ID
,
span
:
span
,
attrs
:
ast
::
ThinVec
::
new
(),
});
let
stmt
=
ast
::
Stmt
{
id
:
ast
::
DUMMY_NODE_ID
,
node
:
ast
::
StmtKind
::
Local
(
local
),
span
:
span
,
};
stmts
.push
(
stmt
);
stmts
.push
(
cx
.stmt_let_type_only
(
span
,
cx
.ty_path
(
assert_path
)));
}
fn
process_variant
(
cx
:
&
mut
ExtCtxt
,
stmts
:
&
mut
Vec
<
ast
::
Stmt
>
,
variant
:
&
VariantData
)
{
for
field
in
variant
.fields
()
{
...
...
src/libsyntax_ext/deriving/cmp/eq.rs
浏览文件 @
62cb7510
...
...
@@ -11,7 +11,7 @@
use
deriving
::
generic
::
*
;
use
deriving
::
generic
::
ty
::
*
;
use
syntax
::
ast
::{
Expr
,
MetaItem
};
use
syntax
::
ast
::{
self
,
Expr
,
MetaItem
};
use
syntax
::
ext
::
base
::{
Annotatable
,
ExtCtxt
};
use
syntax
::
ext
::
build
::
AstBuilder
;
use
syntax
::
parse
::
token
::
InternedString
;
...
...
@@ -23,22 +23,6 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
mitem
:
&
MetaItem
,
item
:
&
Annotatable
,
push
:
&
mut
FnMut
(
Annotatable
))
{
fn
cs_total_eq_assert
(
cx
:
&
mut
ExtCtxt
,
span
:
Span
,
substr
:
&
Substructure
)
->
P
<
Expr
>
{
cs_same_method
(|
cx
,
span
,
exprs
|
{
// create `a.<method>(); b.<method>(); c.<method>(); ...`
// (where method is `assert_receiver_is_total_eq`)
let
stmts
=
exprs
.into_iter
()
.map
(|
e
|
cx
.stmt_expr
(
e
))
.collect
();
let
block
=
cx
.block
(
span
,
stmts
);
cx
.expr_block
(
block
)
},
Box
::
new
(|
cx
,
sp
,
_
,
_
|
{
cx
.span_bug
(
sp
,
"non matching enums in derive(Eq)?"
)
}),
cx
,
span
,
substr
)
}
let
inline
=
cx
.meta_word
(
span
,
InternedString
::
new
(
"inline"
));
let
hidden
=
cx
.meta_list_item_word
(
span
,
InternedString
::
new
(
"hidden"
));
let
doc
=
cx
.meta_list
(
span
,
InternedString
::
new
(
"doc"
),
vec!
[
hidden
]);
...
...
@@ -50,7 +34,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<
additional_bounds
:
Vec
::
new
(),
generics
:
LifetimeBounds
::
empty
(),
is_unsafe
:
false
,
supports_unions
:
fals
e
,
supports_unions
:
tru
e
,
methods
:
vec!
[
MethodDef
{
name
:
"assert_receiver_is_total_eq"
,
generics
:
LifetimeBounds
::
empty
(),
...
...
@@ -66,5 +50,38 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<
}],
associated_types
:
Vec
::
new
(),
};
trait_def
.expand
(
cx
,
mitem
,
item
,
push
)
trait_def
.expand_ext
(
cx
,
mitem
,
item
,
push
,
true
)
}
fn
cs_total_eq_assert
(
cx
:
&
mut
ExtCtxt
,
trait_span
:
Span
,
substr
:
&
Substructure
)
->
P
<
Expr
>
{
fn
assert_ty_bounds
(
cx
:
&
mut
ExtCtxt
,
stmts
:
&
mut
Vec
<
ast
::
Stmt
>
,
ty
:
P
<
ast
::
Ty
>
,
span
:
Span
,
helper_name
:
&
str
)
{
// Generate statement `let _: helper_name<ty>;`,
// set the expn ID so we can use the unstable struct.
let
span
=
super
::
allow_unstable
(
cx
,
span
,
"derive(Eq)"
);
let
assert_path
=
cx
.path_all
(
span
,
true
,
cx
.std_path
(
&
[
"cmp"
,
helper_name
]),
vec!
[],
vec!
[
ty
],
vec!
[]);
stmts
.push
(
cx
.stmt_let_type_only
(
span
,
cx
.ty_path
(
assert_path
)));
}
fn
process_variant
(
cx
:
&
mut
ExtCtxt
,
stmts
:
&
mut
Vec
<
ast
::
Stmt
>
,
variant
:
&
ast
::
VariantData
)
{
for
field
in
variant
.fields
()
{
// let _: AssertParamIsEq<FieldTy>;
assert_ty_bounds
(
cx
,
stmts
,
field
.ty
.clone
(),
field
.span
,
"AssertParamIsEq"
);
}
}
let
mut
stmts
=
Vec
::
new
();
match
*
substr
.fields
{
StaticStruct
(
vdata
,
..
)
=>
{
process_variant
(
cx
,
&
mut
stmts
,
vdata
);
}
StaticEnum
(
enum_def
,
..
)
=>
{
for
variant
in
&
enum_def
.variants
{
process_variant
(
cx
,
&
mut
stmts
,
&
variant
.node.data
);
}
}
_
=>
cx
.span_bug
(
trait_span
,
"unexpected substructure in `derive(Eq)`"
)
}
cx
.expr_block
(
cx
.block
(
trait_span
,
stmts
))
}
src/test/compile-fail/union/union-derive-eq.rs
0 → 100644
浏览文件 @
62cb7510
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(untagged_unions)]
#[derive(Eq)]
// OK
union
U1
{
a
:
u8
,
}
impl
PartialEq
for
U1
{
fn
eq
(
&
self
,
rhs
:
&
Self
)
->
bool
{
true
}
}
#[derive(PartialEq)]
struct
PartialEqNotEq
;
#[derive(Eq)]
union
U2
{
a
:
PartialEqNotEq
,
//~ ERROR the trait bound `PartialEqNotEq: std::cmp::Eq` is not satisfied
}
impl
PartialEq
for
U2
{
fn
eq
(
&
self
,
rhs
:
&
Self
)
->
bool
{
true
}
}
fn
main
()
{}
src/test/compile-fail/union/union-derive.rs
浏览文件 @
62cb7510
...
...
@@ -14,7 +14,6 @@
#[derive(
PartialEq,
//~ ERROR this trait cannot be derived for unions
Eq,
//~ ERROR this trait cannot be derived for unions
PartialOrd,
//~ ERROR this trait cannot be derived for unions
Ord,
//~ ERROR this trait cannot be derived for unions
Hash,
//~ ERROR this trait cannot be derived for unions
...
...
src/test/run-pass/union/union-derive.rs
浏览文件 @
62cb7510
...
...
@@ -15,22 +15,33 @@
#[derive(
Copy,
Clone,
Eq,
)]
union
U
{
a
:
u8
,
b
:
u16
,
}
#[derive(Clone,
Copy)]
impl
PartialEq
for
U
{
fn
eq
(
&
self
,
rhs
:
&
Self
)
->
bool
{
true
}
}
#[derive(
Clone,
Copy,
Eq
)]
union
W
<
T
>
{
a
:
T
,
}
impl
<
T
>
PartialEq
for
W
<
T
>
{
fn
eq
(
&
self
,
rhs
:
&
Self
)
->
bool
{
true
}
}
fn
main
()
{
let
u
=
U
{
b
:
0
};
let
u1
=
u
;
let
u2
=
u
.clone
();
assert
!
(
u1
==
u2
);
let
w
=
W
{
a
:
0
};
let
w1
=
w
.clone
();
assert
!
(
w
==
w1
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录