Rustc error with lambda's and type alias?


#1

The following code gives an error about static lifetimes. Eliminating the type alias makes the error go away. Is this a rustc bug or am I misunderstanding something (maybe re: lifetime elision and type aliases?)?

// this fails:
//    error[E0477]: the type `[closure@compiler-error.rs:5:20: 5:43 g:&mut &mut std::ops::FnMut(u32) -> u32 + 'static]` does not fulfill the required lifetime
type F = FnMut(u32) -> u32;
fn apply_type(f :&mut F, x :u32) -> u32 { f(x) }
fn apply_type_one(g :&mut F, x :u32) -> u32 { 
        let mut adaptor = |x:u32| -> u32 { g(x) };
        apply_type(&mut adaptor,x)
}

// eliminating the type alias = successful compile.
fn apply_type_raw(f :&mut FnMut(u32)->u32, x :u32) -> u32 { f(x) }
fn apply_type_one_raw(g :&mut FnMut(u32)->u32, x :u32) -> u32 {
        let mut adaptor = |x:u32| -> u32 { g(x) };
        apply_type_raw(&mut adaptor,x)
}

fn main() {
}

#2

Yes, this is due to default object bounds. More info here

The way to fix this is to parameterize the type alias with a lifetime and then let elision handle it at use sites:

type F<'a> = FnMut(u32) -> u32 + 'a;

Separately, wanted to point out (in case you’re not aware) that you’re using dynamic dispatch here by virtue of trait objects.


"Trait alias" causing lifetime error
#3

Sweet. Yup, that did it. Shame rustc --explain doesn’t (appear to) have this explanation; would have saved time. Thanks.

The only downside to dynamic dispatch is speed, right?


#4

In this particular example, yeah. The larger topic is generics vs trait objects, and each have their pros/cons (not just in performance, but expressivity and ergonomics as well).

Mostly, I don’t know your familiarity with Rust so wanted to confirm you were opting for what you wanted :slight_smile: