Can't set the lifetime of closure trait director assign to var

For the following code, the code in test_var_direct_error cannot be compiled and ran. it is not possible to assign the returned captured reference of the dyn trait to a variable: it is not possible to specify exact dyn bind type for the variable. how to bind the 'a and 'b lifetime in the function
test_var_direct_error. it can do by generics type alias or generics function arg/return type spec。

pub fn call_fun<'a>(foo: Box<dyn Fn() -> &'a str + 'a>) {
    println!("in call_fun foo() = {}", foo());
}

pub fn args_to_return<'a>(args: Box<dyn Fn() -> &'a str + 'a>) -> Box<dyn Fn() -> &'a str + 'a> {
    args
}

pub type ClType<'a> = Box<dyn Fn() -> &'a str + 'a>;

#[cfg(test)]
mod tests {
    use super::{args_to_return, call_fun, ClType};

    #[test]
    fn test_args_direct() {
        let data = "abc".to_string();
        call_fun(Box::new(|| &data[..]));
    }

    #[test]
    fn test_var_from_fun() {
        let data = "abc".to_string();
        let mut a = args_to_return(Box::new(|| &data[..]));
        call_fun(a);
        a = args_to_return(Box::new(|| &data[..]));
        call_fun(a);
    }

    #[test]
    fn test_var_from_type() {
        let data = "efg".to_string();
        let mut a: ClType = Box::new(|| &data[..]);
        call_fun(a);
        a = Box::new(|| &data[..]);
        call_fun(a);
    }

    #[test]
    fn test_var_direct_error() {
        let data = "ghj".to_string();
        let mut a: Box<dyn Fn() -> &'a str + 'b> = Box::new(|| &data[..]);
        call_fun(a);
        a = Box::new(|| &data[..]);
        call_fun(a);       
    }
}

in stable rust, the only way I know to elide the lifetime is to use a type alias, like test_var_from_type() in your example, but you can do it in nightly using unstable features:

#![feature(unboxed_closures)]

let data = "ghj".to_string();
let mut a: Box<dyn Fn<(), Output = &str> + '_> = Box::new(|| &data[..]);
call_fun(a);
a = Box::new(|| &data[..]);
call_fun(a);
1 Like