Skip to content

FnOnce doesn't seem to support type-based dispatch (as Add, etc. do) #45510

Closed
@eternaleye

Description

@eternaleye

UPDATE: Mentoring instructions below.


Here's a minimal example program showing the issue:

#![feature(fn_traits)] 
#![feature(unboxed_closures)]

struct Ishmael;
struct Maybe;
struct CallMe;

impl FnOnce<(Ishmael,)> for CallMe {
    type Output = ();
    extern "rust-call" fn call_once(self, _args: (Ishmael,)) -> () {
        println!("Split your lungs with blood and thunder!");
    }
}

impl FnOnce<(Maybe,)> for CallMe {
    type Output = ();
    extern "rust-call" fn call_once(self, _args: (Maybe,)) -> () {
        println!("So we just met, and this is crazy");
    }
}

fn main() {
    CallMe(Ishmael);
    CallMe(Maybe);
}

This works perfectly if you comment out either the Ishmael or Maybe 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 mechanism Add::add uses.

In addition, the error message is (to steal lovingly borrow a term from the Perl 6 community) "less than awesome" - it informs the user error[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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions