Open
Description
The following code compiles on stable and nightly. I'm not sure it should as it's effectively casting a Struct::<'a>
to a Struct::<'static>
in safe code.
use std::{any::Any, marker::PhantomData};
fn main() {
bad();
}
fn bad<'a>() -> Struct<'static> {
make_static(|| Struct::<'a>(PhantomData))
}
struct Struct<'a>(PhantomData<&'a ()>);
fn make_static<A, B>(a: A) -> B
where
A: FnOnce0 + 'static,
B: 'static,
{
let boxed: Box<dyn Any + 'static> = Box::new(a.call());
*Box::<dyn Any + 'static>::downcast(boxed).unwrap()
}
trait FnOnce0 {
type Output;
fn call(self) -> Self::Output;
}
impl<F, O> FnOnce0 for F
where
F: FnOnce() -> O,
{
type Output = F::Output;
fn call(self) -> Self::Output {
self()
}
}
It seems lifetime and type parameters that are used in the closure don't affect the lifetime of the closure itself. I stumbled upon this after noticing that || T::default()
is 'static
whereas T::default()
is not.