Add blanket impls to allow the various Fn traits to be interconverted.
Fixes #18387.
This commit is contained in:
parent
63c4f22f2b
commit
680d579ff0
10 changed files with 221 additions and 26 deletions
34
src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
Normal file
34
src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// 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
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
src/test/run-pass/unboxed-closures-extern-fn.rs
Normal file
40
src/test/run-pass/unboxed-closures-extern-fn.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// 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));
|
||||
}
|
||||
|
||||
46
src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
Normal file
46
src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// 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);
|
||||
}
|
||||
|
||||
40
src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
Normal file
40
src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// 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);
|
||||
}
|
||||
|
||||
|
|
@ -12,6 +12,6 @@
|
|||
|
||||
fn main() {
|
||||
let mut zero = |&mut:| {};
|
||||
zero.call_mut(());
|
||||
let () = zero.call_mut(());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue