Auto merge of #55986 - cjgillot:issue-45510, r=nikomatsakis
Allow to dispatch fn traits depending on number of parameters Hello, By following @eddyb's advise on issue #45510, I managed to have the snippets of code in #45510 and #18952 passing without breaking older diagnostics. EDIT: the codegen tests breakage I experienced is due to the poor quality of my laptop. If any kind reviewer has any advice, you are very welcome.
This commit is contained in:
commit
a602f13f02
3 changed files with 308 additions and 144 deletions
56
src/test/run-pass/issue-18952.rs
Normal file
56
src/test/run-pass/issue-18952.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// This issue tests fn_traits overloading on arity.
|
||||
// run-pass
|
||||
|
||||
#![feature(fn_traits)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Fn<(isize, isize)> for Foo {
|
||||
extern "rust-call" fn call(&self, args: (isize, isize)) -> Self::Output {
|
||||
println!("{:?}", args);
|
||||
(args.0 + 1, args.1 + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl FnMut<(isize, isize)> for Foo {
|
||||
extern "rust-call" fn call_mut(&mut self, args: (isize, isize)) -> Self::Output {
|
||||
println!("{:?}", args);
|
||||
(args.0 + 1, args.1 + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl FnOnce<(isize, isize)> for Foo {
|
||||
type Output = (isize, isize);
|
||||
extern "rust-call" fn call_once(self, args: (isize, isize)) -> Self::Output {
|
||||
println!("{:?}", args);
|
||||
(args.0 + 1, args.1 + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Fn<(isize, isize, isize)> for Foo {
|
||||
extern "rust-call" fn call(&self, args: (isize, isize, isize)) -> Self::Output {
|
||||
println!("{:?}", args);
|
||||
(args.0 + 3, args.1 + 3, args.2 + 3)
|
||||
}
|
||||
}
|
||||
|
||||
impl FnMut<(isize, isize, isize)> for Foo {
|
||||
extern "rust-call" fn call_mut(&mut self, args: (isize, isize, isize)) -> Self::Output {
|
||||
println!("{:?}", args);
|
||||
(args.0 + 3, args.1 + 3, args.2 + 3)
|
||||
}
|
||||
}
|
||||
impl FnOnce<(isize, isize, isize)> for Foo {
|
||||
type Output = (isize, isize, isize);
|
||||
extern "rust-call" fn call_once(self, args: (isize, isize, isize)) -> Self::Output {
|
||||
println!("{:?}", args);
|
||||
(args.0 + 3, args.1 + 3, args.2 + 3)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo = Foo;
|
||||
assert_eq!(foo(1, 1), (2, 2));
|
||||
assert_eq!(foo(1, 1, 1), (4, 4, 4));
|
||||
}
|
||||
32
src/test/run-pass/issue-45510.rs
Normal file
32
src/test/run-pass/issue-45510.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Test overloaded resolution of fn_traits.
|
||||
// run-pass
|
||||
|
||||
#![feature(fn_traits)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct Ishmael;
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct Maybe;
|
||||
struct CallMe;
|
||||
|
||||
impl FnOnce<(Ishmael,)> for CallMe {
|
||||
type Output = Ishmael;
|
||||
extern "rust-call" fn call_once(self, _args: (Ishmael,)) -> Ishmael {
|
||||
println!("Split your lungs with blood and thunder!");
|
||||
Ishmael
|
||||
}
|
||||
}
|
||||
|
||||
impl FnOnce<(Maybe,)> for CallMe {
|
||||
type Output = Maybe;
|
||||
extern "rust-call" fn call_once(self, _args: (Maybe,)) -> Maybe {
|
||||
println!("So we just met, and this is crazy");
|
||||
Maybe
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(CallMe(Ishmael), Ishmael);
|
||||
assert_eq!(CallMe(Maybe), Maybe);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue