Skip to content

Commit 9330bae

Browse files
committedMar 23, 2015
Fallout from changing fn traits to use inheritance rather than bridge
impls. This is a [breaking-change] (for gated code) in that when you implement `Fn` (`FnMut`) you must also implement `FnOnce`. This commit demonstrates how to fix it.
1 parent 3760113 commit 9330bae

28 files changed

+216
-59
lines changed
 

‎src/libcollectionstest/btree/set.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,21 @@ struct Counter<'a, 'b> {
4343
}
4444

4545
impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
46-
type Output = bool;
47-
4846
extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
4947
assert_eq!(x, self.expected[*self.i]);
5048
*self.i += 1;
5149
true
5250
}
5351
}
5452

53+
impl<'a, 'b, 'c> FnOnce<(&'c i32,)> for Counter<'a, 'b> {
54+
type Output = bool;
55+
56+
extern "rust-call" fn call_once(mut self, args: (&'c i32,)) -> bool {
57+
self.call_mut(args)
58+
}
59+
}
60+
5561
fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
5662
// FIXME Replace Counter with `Box<FnMut(_) -> _>`
5763
F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,

‎src/test/compile-fail/borrowck-overloaded-call.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,36 @@ struct SFn {
1818
}
1919

2020
impl Fn<(isize,)> for SFn {
21-
type Output = isize;
22-
2321
extern "rust-call" fn call(&self, (z,): (isize,)) -> isize {
2422
self.x * self.y * z
2523
}
2624
}
2725

26+
impl FnMut<(isize,)> for SFn {
27+
extern "rust-call" fn call_mut(&mut self, args: (isize,)) -> isize { self.call(args) }
28+
}
29+
30+
impl FnOnce<(isize,)> for SFn {
31+
type Output = isize;
32+
extern "rust-call" fn call_once(self, args: (isize,)) -> isize { self.call(args) }
33+
}
34+
2835
struct SFnMut {
2936
x: isize,
3037
y: isize,
3138
}
3239

3340
impl FnMut<(isize,)> for SFnMut {
34-
type Output = isize;
35-
3641
extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
3742
self.x * self.y * z
3843
}
3944
}
4045

46+
impl FnOnce<(isize,)> for SFnMut {
47+
type Output = isize;
48+
extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) }
49+
}
50+
4151
struct SFnOnce {
4252
x: String,
4353
}

‎src/test/compile-fail/coerce-unsafe-to-closure.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010

1111
fn main() {
1212
let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
13-
//~^ ERROR: is not implemented for the type
13+
//~^ ERROR E0277
14+
//~| ERROR E0277
1415
}

‎src/test/compile-fail/extern-wrong-value-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ fn main() {
1818
let _x: extern "C" fn() = f; // OK
1919
is_fn(f);
2020
//~^ ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
21-
//~| ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
21+
//~| ERROR the trait `core::ops::FnOnce<()>` is not implemented for the type `extern "C" fn()
2222
}

‎src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,21 @@
1818
struct Foo;
1919
impl Fn<()> for Foo {
2020
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
21-
type Output = ();
22-
23-
extern "rust-call" fn call(&self, args: ()) -> () {}
21+
extern "rust-call" fn call(self, args: ()) -> () {}
2422
}
2523
struct Foo1;
26-
impl Fn() for Foo1 {
24+
impl FnOnce() for Foo1 {
2725
//~^ ERROR associated type bindings are not allowed here
28-
29-
extern "rust-call" fn call(&self, args: ()) -> () {}
26+
extern "rust-call" fn call_once(self, args: ()) -> () {}
3027
}
3128
struct Bar;
3229
impl FnMut<()> for Bar {
3330
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
34-
type Output = ();
35-
3631
extern "rust-call" fn call_mut(&self, args: ()) -> () {}
3732
}
3833
struct Baz;
3934
impl FnOnce<()> for Baz {
4035
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
41-
type Output = ();
42-
4336
extern "rust-call" fn call_once(&self, args: ()) -> () {}
4437
}
4538

‎src/test/compile-fail/fn-trait-formatting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ fn main() {
3535

3636
needs_fn(1);
3737
//~^ ERROR `core::ops::Fn<(isize,)>`
38-
//~| ERROR `core::ops::Fn<(isize,)>`
38+
//~| ERROR `core::ops::FnOnce<(isize,)>`
3939
}

‎src/test/compile-fail/fn-variance-1.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
1717
}
1818

1919
fn main() {
20-
apply(&3, takes_mut); //~ ERROR (values differ in mutability)
2120
apply(&3, takes_imm);
21+
apply(&3, takes_mut);
22+
//~^ ERROR (values differ in mutability)
23+
//~| ERROR (values differ in mutability)
2224

2325
apply(&mut 3, takes_mut);
24-
apply(&mut 3, takes_imm); //~ ERROR (values differ in mutability)
26+
apply(&mut 3, takes_imm);
27+
//~^ ERROR (values differ in mutability)
28+
//~| ERROR (values differ in mutability)
2529
}

‎src/test/compile-fail/issue-15094.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ struct Debuger<T> {
1616
x: T
1717
}
1818

19-
impl<T: fmt::Debug> ops::Fn<(),> for Debuger<T> {
19+
impl<T: fmt::Debug> ops::FnOnce<(),> for Debuger<T> {
2020
type Output = ();
21-
22-
fn call(&self, _args: ()) {
23-
//~^ ERROR `call` has an incompatible type for trait: expected "rust-call" fn, found "Rust" fn
21+
fn call_once(self, _args: ()) {
22+
//~^ ERROR `call_once` has an incompatible type for trait: expected "rust-call" fn, found "Rust" fn
2423
println!("{:?}", self.x);
2524
}
2625
}

‎src/test/compile-fail/issue-20225.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,19 @@
1313
struct Foo;
1414

1515
impl<'a, T> Fn<(&'a T,)> for Foo {
16+
extern "rust-call" fn call(&self, (_,): (T,)) {}
17+
//~^ ERROR: has an incompatible type for trait: expected &-ptr
18+
}
19+
20+
impl<'a, T> FnMut<(&'a T,)> for Foo {
21+
extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
22+
//~^ ERROR: has an incompatible type for trait: expected &-ptr
23+
}
24+
25+
impl<'a, T> FnOnce<(&'a T,)> for Foo {
1626
type Output = ();
1727

18-
extern "rust-call" fn call(&self, (_,): (T,)) {}
28+
extern "rust-call" fn call_once(self, (_,): (T,)) {}
1929
//~^ ERROR: has an incompatible type for trait: expected &-ptr
2030
}
2131

‎src/test/compile-fail/overloaded-calls-bad.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,18 @@ struct S {
1818
}
1919

2020
impl FnMut<(isize,)> for S {
21-
type Output = isize;
22-
2321
extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
2422
self.x * self.y * z
2523
}
2624
}
2725

26+
impl FnOnce<(isize,)> for S {
27+
type Output = isize;
28+
extern "rust-call" fn call_once(mut self, (z,): (isize,)) -> isize {
29+
self.call_mut((z,))
30+
}
31+
}
32+
2833
fn main() {
2934
let mut s = S {
3035
x: 3,

‎src/test/compile-fail/overloaded-calls-nontuple.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@ struct S {
1818
}
1919

2020
impl FnMut<isize> for S {
21-
type Output = isize;
2221
extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
2322
self.x + self.y + z
2423
}
2524
}
2625

26+
impl FnOnce<isize> for S {
27+
type Output = isize;
28+
extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) }
29+
}
30+
2731
fn main() {
2832
let mut s = S {
2933
x: 1,

‎src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,22 @@ use std::ops::{Fn,FnMut,FnOnce};
1919
struct S;
2020

2121
impl FnMut<(isize,)> for S {
22-
type Output = isize;
23-
2422
extern "rust-call" fn call_mut(&mut self, (x,): (isize,)) -> isize {
2523
x * x
2624
}
2725
}
2826

27+
impl FnOnce<(isize,)> for S {
28+
type Output = isize;
29+
30+
extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) }
31+
}
32+
2933
fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
3034
f.call((x,))
3135
}
3236

3337
fn main() {
3438
let x = call_it(&S, 22);
3539
//~^ ERROR not implemented
36-
//~| ERROR not implemented
3740
}

‎src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,19 @@ impl<F,A,R> YCombinator<F,A,R> {
2828
}
2929

3030
impl<A,R,F : FnMut(&mut FnMut(A) -> R, A) -> R> FnMut<(A,)> for YCombinator<F,A,R> {
31-
type Output = R;
32-
3331
extern "rust-call" fn call_mut(&mut self, (arg,): (A,)) -> R {
3432
(self.func)(self, arg)
3533
//~^ ERROR cannot borrow `*self` as mutable more than once at a time
3634
}
3735
}
3836

37+
impl<A,R,F : FnMut(&mut FnMut(A) -> R, A) -> R> FnOnce<(A,)> for YCombinator<F,A,R> {
38+
type Output = R;
39+
extern "rust-call" fn call_once(mut self, args: (A,)) -> R {
40+
self.call_mut(args)
41+
}
42+
}
43+
3944
fn main() {
4045
let mut counter = 0;
4146
let factorial = |recur: &mut FnMut(u32) -> u32, arg: u32| -> u32 {

‎src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,15 @@ fn a() {
2727
}
2828

2929
fn b() {
30-
let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
30+
let y = call_it_mut(&mut square, 22);
31+
//~^ ERROR not implemented
32+
//~| ERROR not implemented
3133
}
3234

3335
fn c() {
34-
let z = call_it_once(square, 22); //~ ERROR not implemented
36+
let z = call_it_once(square, 22);
37+
//~^ ERROR not implemented
38+
//~| ERROR not implemented
3539
}
3640

3741
fn main() { }

‎src/test/compile-fail/unboxed-closures-wrong-abi.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,15 @@ fn a() {
2727
}
2828

2929
fn b() {
30-
let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
30+
let y = call_it_mut(&mut square, 22);
31+
//~^ ERROR not implemented
32+
//~| ERROR not implemented
3133
}
3234

3335
fn c() {
34-
let z = call_it_once(square, 22); //~ ERROR not implemented
36+
let z = call_it_once(square, 22);
37+
//~^ ERROR not implemented
38+
//~| ERROR not implemented
3539
}
3640

3741
fn main() { }

‎src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,15 @@ fn a() {
2828
}
2929

3030
fn b() {
31-
let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
31+
let y = call_it_mut(&mut square, 22);
32+
//~^ ERROR not implemented
33+
//~| ERROR not implemented
3234
}
3335

3436
fn c() {
35-
let z = call_it_once(square, 22); //~ ERROR not implemented
37+
let z = call_it_once(square, 22);
38+
//~^ ERROR not implemented
39+
//~| ERROR not implemented
3640
}
3741

3842
fn main() { }

‎src/test/run-pass/issue-13655.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,27 @@ use std::ops::Fn;
1414
struct Foo<T>(T);
1515

1616
impl<T: Copy> Fn<()> for Foo<T> {
17-
type Output = T;
1817
extern "rust-call" fn call(&self, _: ()) -> T {
1918
match *self {
2019
Foo(t) => t
2120
}
2221
}
2322
}
2423

24+
impl<T: Copy> FnMut<()> for Foo<T> {
25+
extern "rust-call" fn call_mut(&mut self, _: ()) -> T {
26+
self.call(())
27+
}
28+
}
29+
30+
impl<T: Copy> FnOnce<()> for Foo<T> {
31+
type Output = T;
32+
33+
extern "rust-call" fn call_once(self, _: ()) -> T {
34+
self.call(())
35+
}
36+
}
37+
2538
fn main() {
2639
let t: u8 = 1;
2740
println!("{}", Foo(t)());

‎src/test/run-pass/issue-14958.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@ trait Foo { fn dummy(&self) { }}
1515
struct Bar;
1616

1717
impl<'a> std::ops::Fn<(&'a (Foo+'a),)> for Bar {
18-
type Output = ();
1918
extern "rust-call" fn call(&self, _: (&'a Foo,)) {}
2019
}
2120

21+
impl<'a> std::ops::FnMut<(&'a (Foo+'a),)> for Bar {
22+
extern "rust-call" fn call_mut(&mut self, a: (&'a Foo,)) { self.call(a) }
23+
}
24+
25+
impl<'a> std::ops::FnOnce<(&'a (Foo+'a),)> for Bar {
26+
type Output = ();
27+
extern "rust-call" fn call_once(self, a: (&'a Foo,)) { self.call(a) }
28+
}
29+
2230
struct Baz;
2331

2432
impl Foo for Baz {}

‎src/test/run-pass/issue-14959.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,21 @@ impl Alloy {
3434
}
3535

3636
impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile {
37+
extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
38+
}
39+
40+
impl<'b> FnMut<(&'b mut (Response+'b),)> for SendFile {
41+
extern "rust-call" fn call_mut(&mut self, (_res,): (&'b mut (Response+'b),)) {
42+
self.call((_res,))
43+
}
44+
}
45+
46+
impl<'b> FnOnce<(&'b mut (Response+'b),)> for SendFile {
3747
type Output = ();
3848

39-
extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
49+
extern "rust-call" fn call_once(self, (_res,): (&'b mut (Response+'b),)) {
50+
self.call((_res,))
51+
}
4052
}
4153

4254
impl<Rq: Request, Rs: Response> Ingot<Rq, Rs> for HelloWorld {

‎src/test/run-pass/issue-16739.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,36 @@
1818
struct Foo { foo: u32 }
1919

2020
impl FnMut<()> for Foo {
21-
type Output = u32;
2221
extern "rust-call" fn call_mut(&mut self, _: ()) -> u32 { self.foo }
2322
}
2423

25-
impl FnMut<(u32,)> for Foo {
24+
impl FnOnce<()> for Foo {
2625
type Output = u32;
26+
extern "rust-call" fn call_once(mut self, _: ()) -> u32 { self.call_mut(()) }
27+
}
28+
29+
/////////////////////////////////////////////////////////////////////////
30+
31+
impl FnMut<(u32,)> for Foo {
2732
extern "rust-call" fn call_mut(&mut self, (x,): (u32,)) -> u32 { self.foo + x }
2833
}
2934

30-
impl FnMut<(u32,u32)> for Foo {
35+
impl FnOnce<(u32,)> for Foo {
3136
type Output = u32;
37+
extern "rust-call" fn call_once(mut self, args: (u32,)) -> u32 { self.call_mut(args) }
38+
}
39+
40+
/////////////////////////////////////////////////////////////////////////
41+
42+
impl FnMut<(u32,u32)> for Foo {
3243
extern "rust-call" fn call_mut(&mut self, (x, y): (u32, u32)) -> u32 { self.foo + x + y }
3344
}
3445

46+
impl FnOnce<(u32,u32)> for Foo {
47+
type Output = u32;
48+
extern "rust-call" fn call_once(mut self, args: (u32,u32)) -> u32 { self.call_mut(args) }
49+
}
50+
3551
fn main() {
3652
let mut f = box Foo { foo: 42 } as Box<FnMut() -> u32>;
3753
assert_eq!(f.call_mut(()), 42);

‎src/test/run-pass/issue-19982.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,17 @@
1414
struct Foo;
1515

1616
impl<'a> Fn<(&'a (),)> for Foo {
17+
extern "rust-call" fn call(&self, (_,): (&(),)) {}
18+
}
19+
20+
impl<'a> FnMut<(&'a (),)> for Foo {
21+
extern "rust-call" fn call_mut(&mut self, (_,): (&(),)) {}
22+
}
23+
24+
impl<'a> FnOnce<(&'a (),)> for Foo {
1725
type Output = ();
1826

19-
extern "rust-call" fn call(&self, (_,): (&(),)) {}
27+
extern "rust-call" fn call_once(self, (_,): (&(),)) {}
2028
}
2129

2230
fn main() {}

‎src/test/run-pass/overloaded-calls-param-vtables.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,20 @@ use std::ops::Add;
1919
struct G<A>(PhantomData<A>);
2020

2121
impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
22-
type Output = i32;
23-
2422
extern "rust-call" fn call(&self, (arg,): (A,)) -> i32 {
2523
arg.add(1)
2624
}
2725
}
2826

27+
impl<'a, A: Add<i32, Output=i32>> FnMut<(A,)> for G<A> {
28+
extern "rust-call" fn call_mut(&mut self, args: (A,)) -> i32 { self.call(args) }
29+
}
30+
31+
impl<'a, A: Add<i32, Output=i32>> FnOnce<(A,)> for G<A> {
32+
type Output = i32;
33+
extern "rust-call" fn call_once(self, args: (A,)) -> i32 { self.call(args) }
34+
}
35+
2936
fn main() {
3037
// ICE trigger
3138
(G(PhantomData))(1);

‎src/test/run-pass/overloaded-calls-simple.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,38 @@ struct S1 {
1818
}
1919

2020
impl FnMut<(i32,)> for S1 {
21-
type Output = i32;
2221
extern "rust-call" fn call_mut(&mut self, (z,): (i32,)) -> i32 {
2322
self.x * self.y * z
2423
}
2524
}
2625

26+
impl FnOnce<(i32,)> for S1 {
27+
type Output = i32;
28+
extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 {
29+
self.call_mut(args)
30+
}
31+
}
32+
2733
struct S2 {
2834
x: i32,
2935
y: i32,
3036
}
3137

3238
impl Fn<(i32,)> for S2 {
33-
type Output = i32;
3439
extern "rust-call" fn call(&self, (z,): (i32,)) -> i32 {
3540
self.x * self.y * z
3641
}
3742
}
3843

44+
impl FnMut<(i32,)> for S2 {
45+
extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) }
46+
}
47+
48+
impl FnOnce<(i32,)> for S2 {
49+
type Output = i32;
50+
extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) }
51+
}
52+
3953
struct S3 {
4054
x: i32,
4155
y: i32,

‎src/test/run-pass/overloaded-calls-zero-args.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@ struct S {
1818
}
1919

2020
impl FnMut<()> for S {
21-
type Output = i32;
2221
extern "rust-call" fn call_mut(&mut self, (): ()) -> i32 {
2322
self.x * self.y
2423
}
2524
}
2625

26+
impl FnOnce<()> for S {
27+
type Output = i32;
28+
extern "rust-call" fn call_once(mut self, args: ()) -> i32 { self.call_mut(args) }
29+
}
30+
2731
fn main() {
2832
let mut s = S {
2933
x: 3,

‎src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,20 @@ use std::ops::{Fn,FnMut,FnOnce};
1919
struct S;
2020

2121
impl Fn<(i32,)> for S {
22-
type Output = i32;
2322
extern "rust-call" fn call(&self, (x,): (i32,)) -> i32 {
2423
x * x
2524
}
2625
}
2726

27+
impl FnMut<(i32,)> for S {
28+
extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) }
29+
}
30+
31+
impl FnOnce<(i32,)> for S {
32+
type Output = i32;
33+
extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) }
34+
}
35+
2836
fn call_it<F:Fn(i32)->i32>(f: &F, x: i32) -> i32 {
2937
f(x)
3038
}

‎src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ use std::ops::{FnMut,FnOnce};
1919
struct S;
2020

2121
impl FnMut<(i32,)> for S {
22-
type Output = i32;
23-
2422
extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
2523
x * x
2624
}
2725
}
2826

27+
impl FnOnce<(i32,)> for S {
28+
type Output = i32;
29+
30+
extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) }
31+
}
32+
2933
fn call_it_mut<F:FnMut(i32)->i32>(f: &mut F, x: i32) -> i32 {
3034
f(x)
3135
}

‎src/test/run-pass/unboxed-closures-infer-recursive-fn.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,20 @@ impl<F,A,R> YCombinator<F,A,R> {
3030
}
3131

3232
impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> Fn<(A,)> for YCombinator<F,A,R> {
33-
type Output = R;
34-
3533
extern "rust-call" fn call(&self, (arg,): (A,)) -> R {
3634
(self.func)(self, arg)
3735
}
3836
}
3937

38+
impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> FnMut<(A,)> for YCombinator<F,A,R> {
39+
extern "rust-call" fn call_mut(&mut self, args: (A,)) -> R { self.call(args) }
40+
}
41+
42+
impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> FnOnce<(A,)> for YCombinator<F,A,R> {
43+
type Output = R;
44+
extern "rust-call" fn call_once(self, args: (A,)) -> R { self.call(args) }
45+
}
46+
4047
fn main() {
4148
let factorial = |recur: &Fn(u32) -> u32, arg: u32| -> u32 {
4249
if arg == 0 {1} else {arg * recur(arg-1)}

‎src/test/run-pass/unboxed-closures-manual-impl.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ use std::ops::FnMut;
1515
struct S;
1616

1717
impl FnMut<(i32,)> for S {
18-
type Output = i32;
19-
2018
extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
2119
x * x
2220
}
2321
}
2422

23+
impl FnOnce<(i32,)> for S {
24+
type Output = i32;
25+
26+
extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) }
27+
}
28+
2529
fn call_it<F:FnMut(i32)->i32>(mut f: F, x: i32) -> i32 {
2630
f(x) + 3
2731
}

0 commit comments

Comments
 (0)
Please sign in to comment.