This code works:
fn main() {
fn z<'a, 'b>(x: &'a mut std::borrow::Cow<'b, str>) { println!("{}", x); }
let x: &(for<'a> Fn(&'a mut std::borrow::Cow<str>) + 'static) = &z;
let y: &std::any::Any = &x as &std::any::Any;
(y.downcast_ref::<&(for<'a> Fn(&'a mut std::borrow::Cow<str>) + 'static)>().unwrap())(&mut std::borrow::Cow::Borrowed(&*format!("{}", "Foo")));
}
This (supposedly) equivalent code doesn’t:
// https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=cea5893bbeac1f4e5fad0081d1288d08
use std::{sync::Arc, borrow::Cow, any::Any};
struct Handler<T> {
f: Arc<dyn for<'a> Fn(&'a mut T) + 'static>,
}
fn make_handler<T, F: for<'a> Fn(&'a mut T) + 'static>(f: F) -> Handler<T> {
Handler { f: Arc::new(f) }
}
fn main() {
fn z<'a, 'b>(x: &'a mut Cow<'b, str>) { println!("{}", x); }
let x: Handler<Cow<str>> = make_handler(z);
let y: &Any = &x as &Any;
(y.downcast_ref::<Handler<Cow<str>>>().unwrap().f)(&mut Cow::Borrowed(&*format!("{}", "Foo")));
}
Can we somehow make the latter code also work? (with whatever syntax we can come up with)
This would have important consequences for both futures and my eventbus, and we know the code is sound because the first variant works. Otherwise, I guess my only other option is something like this unsafe mess: (I believe futures or tokio or something has something like this)
struct UnsafelyForAnyLifetime<T> {
v: *mut T
}
impl<T> UnsafelyForAnyLifetime<T> {
/// unsafe because you need to put T somewhere on the stack
unsafe fn new(t: &mut T) -> self {
Self { v: t as *mut T }
}
/// safe because it follows the lifetime of the self, and thus can't
/// escape an for<'a> Fn(&'a mut ...) (aka the intended usage)
fn get_mut<'a>(&'a mut self) -> &'a mut T {
unsafe { &mut *self.v }
}
/// safe because same as above
fn get<'a>(&'a self) -> &'a T {
unsafe { &*self.v }
}
}