Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
680d579f
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,发现更多精彩内容 >>
提交
680d579f
编写于
10月 28, 2014
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add blanket impls to allow the various `Fn` traits to be interconverted.
Fixes #18387.
上级
63c4f22f
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
221 addition
and
26 deletion
+221
-26
src/libcore/ops.rs
src/libcore/ops.rs
+50
-20
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/select.rs
+3
-3
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/mod.rs
+5
-0
src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
+34
-0
src/test/run-pass/issue-16668.rs
src/test/run-pass/issue-16668.rs
+2
-2
src/test/run-pass/unboxed-closures-extern-fn.rs
src/test/run-pass/unboxed-closures-extern-fn.rs
+40
-0
src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
+46
-0
src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
+40
-0
src/test/run-pass/unboxed-closures-manual-impl.rs
src/test/run-pass/unboxed-closures-manual-impl.rs
+0
-0
src/test/run-pass/unboxed-closures-zero-args.rs
src/test/run-pass/unboxed-closures-zero-args.rs
+1
-1
未找到文件。
src/libcore/ops.rs
浏览文件 @
680d579f
...
...
@@ -866,13 +866,45 @@ pub trait FnOnce<Args,Result> {
extern
"rust-call"
fn
call_once
(
self
,
args
:
Args
)
->
Result
;
}
macro_rules!
def_fn_mut
(
impl
<
F
,
A
,
R
>
FnMut
<
A
,
R
>
for
F
where
F
:
Fn
<
A
,
R
>
{
extern
"rust-call"
fn
call_mut
(
&
mut
self
,
args
:
A
)
->
R
{
self
.call
(
args
)
}
}
impl
<
F
,
A
,
R
>
FnOnce
<
A
,
R
>
for
F
where
F
:
FnMut
<
A
,
R
>
{
extern
"rust-call"
fn
call_once
(
mut
self
,
args
:
A
)
->
R
{
self
.call_mut
(
args
)
}
}
impl
<
Result
>
Fn
<
(),
Result
>
for
extern
"Rust"
fn
()
->
Result
{
#[allow(non_snake_case)]
extern
"rust-call"
fn
call
(
&
self
,
_
args
:
())
->
Result
{
(
*
self
)()
}
}
impl
<
Result
,
A0
>
Fn
<
(
A0
,),
Result
>
for
extern
"Rust"
fn
(
A0
)
->
Result
{
#[allow(non_snake_case)]
extern
"rust-call"
fn
call
(
&
self
,
args
:
(
A0
,))
->
Result
{
let
(
a0
,)
=
args
;
(
*
self
)(
a0
)
}
}
macro_rules!
def_fn
(
(
$
(
$args:ident
)
*
)
=>
(
impl
<
Result
$
(,
$args
)
*>
Fn
Mut
<
(
$
(
$args
,)
*
),
Result
>
Fn
<
(
$
(
$args
,)
*
),
Result
>
for
extern
"Rust"
fn
(
$
(
$args
:
$args
,)
*
)
->
Result
{
#[allow(non_snake_case)]
extern
"rust-call"
fn
call
_mut
(
&
mut
self
,
args
:
(
$
(
$args
,)
*
))
->
Result
{
extern
"rust-call"
fn
call
(
&
self
,
args
:
(
$
(
$args
,)
*
))
->
Result
{
let
(
$
(
$args
,)
*
)
=
args
;
(
*
self
)(
$
(
$args
,)
*
)
}
...
...
@@ -880,20 +912,18 @@ extern "rust-call" fn call_mut(&mut self, args: ($($args,)*)) -> Result {
)
)
def_fn_mut!
()
def_fn_mut!
(
A0
)
def_fn_mut!
(
A0
A1
)
def_fn_mut!
(
A0
A1
A2
)
def_fn_mut!
(
A0
A1
A2
A3
)
def_fn_mut!
(
A0
A1
A2
A3
A4
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
)
def_fn_mut!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
)
def_fn!
(
A0
A1
)
def_fn!
(
A0
A1
A2
)
def_fn!
(
A0
A1
A2
A3
)
def_fn!
(
A0
A1
A2
A3
A4
)
def_fn!
(
A0
A1
A2
A3
A4
A5
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
)
def_fn!
(
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
)
src/librustc/middle/traits/select.rs
浏览文件 @
680d579f
...
...
@@ -804,12 +804,12 @@ fn candidate_from_obligation_no_cache(&mut self,
&
candidates
[
i
],
&
candidates
[
j
]));
if
is_dup
{
debug!
(
"Dropping candidate #{}/
#
{}: {}"
,
debug!
(
"Dropping candidate #{}/{}: {}"
,
i
,
candidates
.len
(),
candidates
[
i
]
.repr
(
self
.tcx
()));
candidates
.swap_remove
(
i
);
}
else
{
debug!
(
"Retaining candidate #{}/
#
{}"
,
i
,
candidates
.len
());
debug!
(
"Retaining candidate #{}/
{}:
{}"
,
i
,
candidates
.len
()
,
candidates
[
i
]
.repr
(
self
.tcx
())
);
i
+=
1
;
}
}
...
...
src/librustc/middle/typeck/check/mod.rs
浏览文件 @
680d579f
...
...
@@ -3493,6 +3493,11 @@ fn check_unboxed_closure(fcx: &FnCtxt,
ast
::
FnOnceUnboxedClosureKind
=>
ty
::
FnOnceUnboxedClosureKind
,
};
debug!
(
"unboxed_closure for {} --> sig={} kind={}"
,
local_def
(
expr
.id
)
.repr
(
fcx
.tcx
()),
fn_ty
.sig
.repr
(
fcx
.tcx
()),
kind
);
let
unboxed_closure
=
ty
::
UnboxedClosure
{
closure_type
:
fn_ty
,
kind
:
kind
,
...
...
src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
0 → 100644
浏览文件 @
680d579f
// Copyright 2014 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.
// Checks that the Fn trait hierarchy rules do not permit
// Fn to be used where FnMut is implemented.
#![feature(unboxed_closure_sugar)]
#![feature(overloaded_calls)]
use
std
::
ops
::{
Fn
,
FnMut
,
FnOnce
};
struct
S
;
impl
FnMut
<
(
int
,),
int
>
for
S
{
extern
"rust-call"
fn
call_mut
(
&
mut
self
,
(
x
,):
(
int
,))
->
int
{
x
*
x
}
}
fn
call_it
<
F
:
Fn
(
int
)
->
int
>
(
f
:
&
F
,
x
:
int
)
->
int
{
f
.call
((
x
,))
}
fn
main
()
{
let
x
=
call_it
(
&
S
,
22
);
//~ ERROR not implemented
}
src/test/run-pass/issue-16668.rs
浏览文件 @
680d579f
...
...
@@ -20,8 +20,8 @@ impl<'a, I, O: 'a> Parser<'a, I, O> {
fn
compose
<
K
:
'a
>
(
mut
self
,
mut
rhs
:
Parser
<
'a
,
O
,
K
>
)
->
Parser
<
'a
,
I
,
K
>
{
Parser
{
parse
:
box
move
|
&
mut
:
x
:
I
|
{
match
self
.parse
.call_mut
((
x
,))
{
Ok
(
r
)
=>
rhs
.parse
.call_mut
((
r
,)),
match
(
*
self
.parse
)
.call_mut
((
x
,))
{
Ok
(
r
)
=>
(
*
rhs
.parse
)
.call_mut
((
r
,)),
Err
(
e
)
=>
Err
(
e
)
}
}
...
...
src/test/run-pass/unboxed-closures-extern-fn.rs
0 → 100644
浏览文件 @
680d579f
// Copyright 2014 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.
// Checks that extern fn points implement the full range of Fn traits.
#![feature(unboxed_closure_sugar)]
#![feature(overloaded_calls)]
use
std
::
ops
::{
Fn
,
FnMut
,
FnOnce
};
fn
square
(
x
:
int
)
->
int
{
x
*
x
}
fn
call_it
<
F
:
Fn
(
int
)
->
int
>
(
f
:
&
F
,
x
:
int
)
->
int
{
f
.call
((
x
,))
}
fn
call_it_mut
<
F
:
FnMut
(
int
)
->
int
>
(
f
:
&
mut
F
,
x
:
int
)
->
int
{
f
.call_mut
((
x
,))
}
fn
call_it_once
<
F
:
FnOnce
(
int
)
->
int
>
(
f
:
F
,
x
:
int
)
->
int
{
f
.call_once
((
x
,))
}
fn
main
()
{
let
x
=
call_it
(
&
square
,
22
);
let
y
=
call_it_mut
(
&
mut
square
,
22
);
let
z
=
call_it_once
(
square
,
22
);
assert_eq!
(
x
,
square
(
22
));
assert_eq!
(
y
,
square
(
22
));
assert_eq!
(
z
,
square
(
22
));
}
src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
0 → 100644
浏览文件 @
680d579f
// Copyright 2014 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.
// Checks that the Fn trait hierarchy rules permit
// any Fn trait to be used where Fn is implemented.
#![feature(unboxed_closure_sugar)]
#![feature(overloaded_calls)]
use
std
::
ops
::{
Fn
,
FnMut
,
FnOnce
};
struct
S
;
impl
Fn
<
(
int
,),
int
>
for
S
{
extern
"rust-call"
fn
call
(
&
self
,
(
x
,):
(
int
,))
->
int
{
x
*
x
}
}
fn
call_it
<
F
:
Fn
(
int
)
->
int
>
(
f
:
&
F
,
x
:
int
)
->
int
{
f
.call
((
x
,))
}
fn
call_it_mut
<
F
:
FnMut
(
int
)
->
int
>
(
f
:
&
mut
F
,
x
:
int
)
->
int
{
f
.call_mut
((
x
,))
}
fn
call_it_once
<
F
:
FnOnce
(
int
)
->
int
>
(
f
:
F
,
x
:
int
)
->
int
{
f
.call_once
((
x
,))
}
fn
main
()
{
let
x
=
call_it
(
&
S
,
22
);
let
y
=
call_it_mut
(
&
mut
S
,
22
);
let
z
=
call_it_once
(
S
,
22
);
assert_eq!
(
x
,
y
);
assert_eq!
(
y
,
z
);
}
src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
0 → 100644
浏览文件 @
680d579f
// Copyright 2014 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.
// Checks that the Fn trait hierarchy rules permit
// FnMut or FnOnce to be used where FnMut is implemented.
#![feature(unboxed_closure_sugar)]
#![feature(overloaded_calls)]
use
std
::
ops
::{
FnMut
,
FnOnce
};
struct
S
;
impl
FnMut
<
(
int
,),
int
>
for
S
{
extern
"rust-call"
fn
call_mut
(
&
mut
self
,
(
x
,):
(
int
,))
->
int
{
x
*
x
}
}
fn
call_it_mut
<
F
:
FnMut
(
int
)
->
int
>
(
f
:
&
mut
F
,
x
:
int
)
->
int
{
f
.call_mut
((
x
,))
}
fn
call_it_once
<
F
:
FnOnce
(
int
)
->
int
>
(
f
:
F
,
x
:
int
)
->
int
{
f
.call_once
((
x
,))
}
fn
main
()
{
let
y
=
call_it_mut
(
&
mut
S
,
22
);
let
z
=
call_it_once
(
S
,
22
);
assert_eq!
(
y
,
z
);
}
src/test/run-pass/
fn-trait-sugar
.rs
→
src/test/run-pass/
unboxed-closures-manual-impl
.rs
浏览文件 @
680d579f
文件已移动
src/test/run-pass/unboxed-closures-zero-args.rs
浏览文件 @
680d579f
...
...
@@ -12,6 +12,6 @@
fn
main
()
{
let
mut
zero
=
|
&
mut
:|
{};
zero
.call_mut
(());
let
()
=
zero
.call_mut
(());
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录