3

I'm learning Rust and thought I'd try to make a very simple reactive stream library. A sample of the code is below:

trait Observable<T> {
    // some stuff for emitting values when requested
}

trait Mappable<T, U> {
    fn map(self, f: fn(&T) -> U) -> Box<dyn Observable<U>>;
}

struct Just<T> {
    value: T
}

impl<T> Observable<T> for Just<T> {}

impl<T, U: 'static> Mappable<T, U> for Just<T> {
    fn map(self, f: fn(&T) -> U) -> Box<dyn Observable<U>> {
        Box::new(Just { value: f(&self.value) })
    }
}

In order to make it work, I need to give a 'static lifetime to the U type in the implementation of Mappable for Just. Without it, the compiler complains:

error[E0310]: the parameter type `U` may not live long enough
  --> src/lib.rs:17:9
   |
15 |   impl<T, U> Mappable<T, U> for Just<T> {
   |           - help: consider adding an explicit lifetime bound `U: 'static`...
16 |       fn map(self, f: fn(&T) -> U) -> Box<dyn Observable<U>> {
17 | /         Box::new(Just {
18 | |             value: f(&self.value),
19 | |         })
   | |__________^
   |
note: ...so that the type `Just<U>` will meet its required lifetime bounds
  --> src/lib.rs:17:9
   |
17 | /         Box::new(Just {
18 | |             value: f(&self.value),
19 | |         })
   | |__________^

I don't understand why the compiler is complaining about this because the value is placed inside a Box.

Providing the 'static lifetime obviously works but I'm concerned that it would create a memory leak as intermediate stages in the stream would not be free'd until the program exits.

I think the solution is to make the lifetime of U be the same as T. But all my attempts at doing this have failed.

How can I express the above code without using 'static?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Oli
  • 1,112
  • 1
  • 10
  • 25
  • It looks like you think that `'static` here means that the boxed value will live forever, but that is when it refers to references. Here, it constraints a type, it just means that `U` will not contain non-static references. – rodrigo Sep 11 '18 at 09:42
  • I believe your question is answered by the answers of [The compiler suggests I add a 'static lifetime because the parameter type may not live long enough, but I don't think that's what I want](https://stackoverflow.com/q/40053550/155423). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Sep 11 '18 at 12:18
  • 2
    [The duplicate applied to your question](https://play.rust-lang.org/?gist=149b51e36b4be4956e9a9ad9c382fd96&version=stable&mode=debug&edition=2015) – Shepmaster Sep 11 '18 at 12:21
  • @Shepmaster it looks like your rust example does the trick, now I just have to read up on this syntax: `dyn Observable + 'a` – Oli Sep 11 '18 at 12:47
  • 1
    @Oli I added a duplicate Q for what the syntax is: [Why is adding a lifetime to a trait with the plus operator (Iterator + 'a) needed?](https://stackoverflow.com/q/42028470/155423). – Shepmaster Sep 11 '18 at 12:50

0 Answers0