How to pretend something lives for 'static


#1

How can I tell the compiler to shut up and accept a value as if it lived for 'static, no matter the requirements on type parameters? How could I get the example below to work?

use std::mem::transmute;

struct Foo<'a, T: 'a>(&'a T);

fn take_foo<'a, T: 'a>(x : Foo<'a, T>) {
  // How can I lie here and claim f lives for 'static?
    need_static(x)
    // This doesn't work.
    //need_static(transmute::<Foo<'a, T>, Foo<'static, T>>(x))
}

fn need_static<T: 'static>(_:T) {}

playground


#2

There’s a second lifetime embedded in T:

fn take_foo<'a, T: 'static /* was 'a here */>(x : Foo<'a, T>) {
    unsafe {need_static(transmute::<Foo<'a, T>, Foo<'static, T>>(x))}
}

Although I don’t know how to change that with just transmute.


#3

Unfortunately, it’s impossible to have &'static T where T is not : 'static. That limitation is the motivation for 'unsafe lifetime RFC (although it wouldn’t help in this exact case either).


#4

Why does your need_static need 'static? There may be other alternatives for that part…


#5

The real use case was trying to upgrade rayon to futures 0.0.14 and get rid of the Unpark trait object in the process. Futures wants an Arc<T: Unpark + 'static> but rayon has

struct ScopeFutureContents<'scope, F: Future + 'scope, S: FutureScope<'scope>>

I wanted to say "consider this ScopeFutureContents as 'static" but found no way to do it so gave up for now.


#6

Ah, yeah, becoming a trait object is part of how it can lie about the lifetimes. For other’s reference, that’s in make_unpark.

Which futures API are you talking about though? Because I thought most of it already takes Arc<Unpark>, a trait object, so I’m not sure what you’re trying to avoid. But since Unpark is deprecated, we should see if the new Notify helps the situation.


#7

I opened an issue in rayon where we can contine the rayon-specific discussion.