-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Implementation of Trait for different type of Fn doesn't work #60074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm pretty sure this is a known issue, but can't find an issue to reference right now |
This is an issue because a closure could implement both impl FnOnce<(u32,)> for Foo {
type Output = u32;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
args.0
}
}
impl FnOnce<(u32, u32)> for Foo {
type Output = u32;
extern "rust-call" fn call_once(self, args: (u32, u32)) -> Self::Output {
args.0
}
} There might be some way to make this work in the future with a new language feature, there's probably an issue about it open somewhere. |
For example through variadic closures. |
@Centril I was more thinking of something like forcing Alternatively something related to specialization so that both implementations can be provided and overlap could be dealt with. But maybe variadic closures could do it as well. |
@Nemo157 Sure; I was mostly thinking in terms of what can be done without a stable ability to implement these |
Is there some workaround available for this issue? The best i can come up with right now is to wrap the functions in newtypes, which is slightly uncomfortable. |
|
@djugei was you able to wrap? i tried to wrap with into and from impls, but it said to me that somebody already impls these. |
Why is this considered conflicting implementations? trait Function {
fn call(&self) -> i32;
}
impl<F: Fn() -> Result<i32, bool>> Function for F {
fn call(&self) -> i32 {
self().unwrap()
}
}
impl<F: Fn() -> i32> Function for F {
fn call(&self) -> i32 {
self()
}
}
// error[E0119]: conflicting implementations of trait `Function` @Nemo157 mentioned that the original example is an is an issue because a closure could implement both struct Foo;
impl FnOnce<()> for Foo {
type Output = i32;
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
1
}
}
impl FnOnce<()> for Foo {
type Output = Result<i32, bool>;
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
Ok(1)
}
}
// error[E0119]: conflicting implementations of trait `std::ops::FnOnce<()>` for type `Foo` |
@ibraheemdev yes, this is weird... https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=f36063e2e6f332af7b6e261d3667bcfe |
I saw that actix web has a solution for implementing a common interface across different The basic idea is to make the base trait generic and specialize different variants of the trait depending on the argument list of the |
Implementing a Trait for a type T (where T is a function with a given a signature) and then trying to implement the same trait for another type T (where T is a function with a different signature) doesn't compile.
I tried this code:
When compiling this code I get :
What I would expect is that T here represent in the first implementation either a fn(u32) -> u32 or a closure the implement Fn(u32) -> u32, then in the second implementation, T would be either a fn(u32, u32) -> u32 or a closure the implement Fn(u32, u32) -> u32.
Meta
rustc 1.34.0 (91856ed 2019-04-10)
binary: rustc
commit-hash: 91856ed
commit-date: 2019-04-10
host: x86_64-apple-darwin
release: 1.34.0
LLVM version: 8.0
The text was updated successfully, but these errors were encountered: