Keeley Hoek
Keeley Hoek

Reputation: 543

Rust type mismatch resolving `for<'r> ...` with closure trait alias argument

Trait aliases aren't in stable Rust right now, but I tried to emulate them (giving a nicer name to a particular kind of closure) by doing

trait MyCallback: FnMut(&u32) -> () { }

impl<F: FnMut(&u32) -> ()> MyCallback for F { }

which has worked great for other kinds of trait aliases I've needed. But then when I tried to use the trait alias, I had lifetime problems(?) which I couldn't resolve. Consider the following two duplicate functions, just with MyCallback replaced with its "definition" in the second case.

fn process_data(mut f: impl MyCallback) -> () {
    f(&0)
}

fn process_data_2(mut f: impl FnMut(&u32) -> ()) -> () {
    f(&0)
}

fn main() {
    // Doesn't compile
    process_data(|_| ());

    // Compiles
    process_data_2(|_| ());
}

(Complete example on the Playground.) As commented, the function using the alias won't accept the argument I want to pass it. I would guess that I need to manually insert some lifetimes in the trait definition to emulate what the compiler is implicitly doing as it parses process_data_2, but I can't figure out how to proceed (my attempts to insert for<'a> clauses, which I just learnt about, all failed).

How can I make my code compile?

Upvotes: 4

Views: 538

Answers (2)

Sean
Sean

Reputation: 123

If I understand your post, you are trying to use the trait to create a "callback" type. If that is indeed the case, you're better off using a function alias, like this:

pub type MyCallback = fn(&u32) -> ();

fn process_data(mut f: MyCallback) -> () {
    f(&0)
}

The error message you're getting is due to the issue that nnnmmm posted above... right as I was typing this post :p

Upvotes: 1

nnnmmm
nnnmmm

Reputation: 8784

To make it compile, you can add a type annotation to your closure:

process_data(|_: &u32| ());

This seems to be related to this longstanding issue.

Upvotes: 4

Related Questions