Rust: There’s more to 'static than might meet the eye

Unegare
2 min readMar 29, 2023

It’s no mystery that the first use-case scenario of 'static which crosses one’s mind is that one in conjunction with a reference. Say, &'static str . Anyone and everyone has declared such const (in)variables in their code now and then. Furthermore, it is imperative to put that explicit apostrophe with extra inscription following. It can’t be omitted since consts are presupposed to outlast the whole runtime.

At the top of a novice head it might seem the unique context where it is appropriate to specify lifetime . Yet it’s just not so.

Let’s take a look at the following code:

struct Service<SS: ServiceSetup> {
ss: SS,
}

trait ServiceSetup { }

That is some service depending on a generic type which should somehow customise the service. Quite common or garden, isn’t it?

Now, let’s imagine that we are willing to dress up our programme with some sort of async stuff. Say, channels like tokio::sync::mpsc, futures::channel::mpscor even tokio::sync::broadcast, why not? On top of that, we’d opt for not only choking the pipe but flushing it out as well, or else it would be utterly pointless performance.

How do you go about tokio::spawning an async block for that digesting task? If you are with me, you would go along with the statement that it can have its uses to have the exact type passed through the pipe being part of the generic ServiceSetup thing.

struct Service<SS: ServiceSetup> {
ss: SS,
}

trait ServiceSetup {
type Message;
}

Now, what are the prerequisites for the type Message to be dishable around within the async block ? It happens to be something staggering.

struct Servie<SS: ServiceSetup> {
chan: broadcast::Sender<SS::Message>,
ss: SS,
}

trait ServiceSetup {
type Message: Send + Sync + 'static;
}

At first, it might be stupefying for an unseasoned user, to impose such a lifetime requirement without & the ref symbol, or not as a generic parameter for a struct, but just as a constraint on the par with traits. Yet this is how it is.

No wonder, it must be Send and Sync , but it’s not enough. It must be independent of the scope where it was created, i.e. it must be something without outward references. How to specify it? By dint of the very 'static to begin with.

All in all, this extra bound should not be mixed up with that one of a reference. Since it does not require the underlying type to be everlasting for the duration of the runtime, but just without outward references.

--

--