Reputation: 543
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
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
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