-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
FnOnce
doesn't seem to support type-based dispatch (as Add
, etc. do)
#45510
Comments
Incidentally, disallowing it doesn't really reduce people's ability to write multi-dispatch - it just makes it uglier. Consider the atrocity I just perpetrated (to see if I could): use std::ops::Add;
struct Ishmael;
struct Maybe;
struct CallMe;
impl Add<Ishmael> for CallMe {
type Output = ();
fn add(self, _args: (Ishmael)) -> () {
println!("Split your lungs with blood and thunder!");
}
}
impl Add<Maybe> for CallMe {
type Output = ();
fn add(self, _args: (Maybe)) -> () {
println!("So we just met, and this is crazy");
}
}
impl Add<(Ishmael, Maybe)> for CallMe {
type Output = ();
fn add(self, _args: (Ishmael, Maybe)) -> () {
println!("But I didn't know salty captains liked pop");
}
}
fn main() {
CallMe+(Ishmael);
CallMe+(Maybe);
CallMe+(Ishmael, Maybe);
} |
cc @rust-lang/lang Given that, in the future, Variadic Generics would almost certainly allow arity dispatch (if we ever get them), and that AIUI, the fix involves generating an N-tuple of inference variables for an N-argument call, i.e. instead of searching for |
As @nikomatsakis is no longer opposed to the fix, here's some context for it: rust/src/librustc_typeck/check/callee.rs Lines 168 to 172 in 3bd4af8
It's equivalent to this: Some(&[self.next_ty_var(TypeVariableOrigin::TypeInference(call_expr.span))]) Instead, rust/src/librustc_typeck/check/callee.rs Lines 45 to 48 in 3bd4af8
should be passed down through |
@eddyb I figured I would give this a try. I've got the above example compiling, but I'm just looking into a few failures that probably have something to do with resolving closure checks in |
@sifkarov Can you open a pull request? Could be just a pre-existing bug that gets exposed by this. |
@eddyb I think the issue was more or less just me being silly... I'll open a pull request shortly. |
@sifkarov Did you ever make a PR for this? |
I've run into a problem that I think is the converse of this. I am trying to implement wrappers for an integration library, and want to automatically handle functions of any number of dimensions, so something like this: trait Integrand {
...
}
impl<F> Integrand for Fn(f64) -> f64 {
...
}
impl<F> Integrand for Fn(f64, f64) -> f64 {
...
} But the compiler gives me a "conflicting implementation" error, since it sees both cases as |
@jhod0 Did you mean impl<F: Fn(f64) -> f64 + Fn(f64, f64) -> f64> Integrand for F {
// here you'd have to choose which "overload" to use if both exist
} |
Allow to dispatch fn traits depending on number of parameters Hello, By following @eddyb's advise on issue rust-lang#45510, I managed to have the snippets of code in rust-lang#45510 and rust-lang#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.
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 seems like it has been fixed (by #55986) and can be closed, no? |
This does appear to be fixed by #55986. Closing as fixed. |
UPDATE: Mentoring instructions below.
Here's a minimal example program showing the issue:
This works perfectly if you comment out either the
Ishmael
orMaybe
implementations, and the corresponding call. I've wanted this behavior at various times - if nothing else, it'd be useful for binding to certain parts of C++ - and at least in theory it's the same exact mechanismAdd::add
uses.In addition, the error message is (to
steallovingly borrow a term from the Perl 6 community) "less than awesome" - it informs the usererror[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
when it clearly is (as it succeeds in the single-impl case).It also claims
error[E0619]: the type of this value must be known in this context
, but only for the argument of the first call - reversing the order also exchanges the subject of the error message.Should this be supported? If so, what needs done? If not, how can we make the error messages more helpful? Not supporting it now and adding support later is forwards-compatible, but at very least the error message should probably be improved before stabilization (cc #29625)
EDIT: Ah, seems this may be covered by #18952
The text was updated successfully, but these errors were encountered: