Storing arbitrary Fn in Any

Fun fact, this works:

fn main() {
    fn z<'a, 'b>(x: &'a mut std::borrow::Cow<'b, str>) { println!("{}", x); }
    let x: &(dyn for<'a> Fn(&'a mut std::borrow::Cow<str>) + 'static) = &z;
    let y: &dyn std::any::Any = &x as &dyn std::any::Any;
    (y.downcast_ref::<&(dyn for<'a> Fn(&'a mut std::borrow::Cow<str>) + 'static)>().unwrap())(&mut std::borrow::Cow::Borrowed(&*format!("{}", "Foo")));
}

(compiler infers a hidden lifetime in the for<'a> Fn(&'a mut std::borrow::Cow<str>) + 'static, turning it into for<'a, 'r> Fn(&'a mut std::borrow::Cow<'r, str>) + 'static)

This (supposedly) equivalent code doesn't:

type MyFn<T> = dyn for<'a> Fn(&'a mut T) + 'static;
fn main() {
    fn z<'a, 'b>(x: &'a mut std::borrow::Cow<'b, str>) { println!("{}", x); }
    let x: &MyFn<std::borrow::Cow<str>> = &z;
    let y: &dyn std::any::Any = &x as &dyn std::any::Any;
    (y.downcast_ref::<&MyFn<std::borrow::Cow<str>>>().unwrap())(&mut std::borrow::Cow::Borrowed(&*format!("{}", "Foo")));
}

This is a limitation of Rust, and one that should be fixed. This limitation disallows a lot of perfectly safe code and requires the use of dangerously unsafe workarounds.


And then there's this:

fn main() {
    type MyFn<T> = dyn for<'a> Fn(&'a mut T) + 'static;
    type MyFnCowstr = dyn for<'a> Fn(&'a mut std::borrow::Cow<str>) + 'static;
    let foo: &MyFnCowstr = &|a| println!("{}", a);
    let bar: &MyFn<_> = foo;
    
    // this works
    bar(&mut std::borrow::Cow::Borrowed(&String::new()));
    
    let foo_any: &std::any::Any = &foo as &std::any::Any;
    let foo_back = foo_any.downcast_ref::<&MyFnCowstr>().unwrap();
    // this works
    foo_back(&mut std::borrow::Cow::Borrowed(&String::new()));
    
    // UNCOMMENT the following code to break the code above.
    /*
    let bar_any: &std::any::Any = &bar as &std::any::Any;
    // */
}