0

In a large code base I am changing the implementation of a component used all over the place. Many, many structs contain instances of it.

Lets say its

  pub struct Engine{
      thing: Widget,
      .....         
  }

and users of it have

  struct Woosh{
      engine : Engine,
      ...
  }  

The new implementation uses a widget (from a component library) thats like this

  pub struct Widget2<'a>{
      goop: Stuff<'a>,
      ....
  }

so I have

  pub struct Engine{
      thing: Widget2
      ...
  }

but of course that doesnt work it has to be

  pub struct Engine<'a>{
      thing: Widget2<'a>
      ...
  }

But now all my callers have to change too

  struct Woosh<'a>{
      engine : Engine<'a>,
      ...
  }  

and their callers and so on, I Have to touch a huge percentage of the code base for what should have been a transparent implementation switch down in the engine room.

Is there anyway to chop off that 'a chain. I know I can do it if I change Widget2 and get rid of whats causing it to need the lifetime specifier, but that not my code

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
pm100
  • 48,078
  • 23
  • 82
  • 145
  • to remove a lifetime, you can choice to remove the lifetime ^^'. I generally recommend to avoid lifetime in structure unless you really know what you are doing. Maybe you should own the data or use Rc. – Stargateur Jun 03 '23 at 18:20
  • 4
    You might be in trouble here. Does it compile if you use `thing: Widget2<'static>`? That kind of thing [sometimes helps](https://stackoverflow.com/a/69845360/1600898). If not, is the resource `Widget2` refers to a singleton? If so, you might be able to leak it (using `Box::leak(Box::new(...))`), and again use `thing: Widget2<'static>`. Finally, if you're adventurous, you might bundle make `Engine` a self-referential struct using crates like [ouroboros](https://docs.rs/ouroboros/latest/ouroboros/) or [self_cell](https://crates.io/crates/self_cell), and store `thing: Widget2<'self>` in it. – user4815162342 Jun 03 '23 at 18:28
  • @Stargateur - the 'a on Widget2 is not my code, its code in a crate that I want to use – pm100 Jun 03 '23 at 18:49
  • @user4815162342 I dont see how making it self referential helps – pm100 Jun 06 '23 at 00:07
  • @pm100 The idea behind self-referential types is that you can store the data and the reference to the data in the same structure. The reference uses a special lifetime like `'self` or `'this`, that denotes the data. This lifetime is special in that it's not defned on the outer structure as lifetimes normally are (it's a special case like `'static`). Here the idea is that `Engine<'a>` refers to *some* data that carries the lifetime `<'a>`. A self-referential crate would allow you store that data, whatever it is, alongside the Engine. – user4815162342 Jun 06 '23 at 06:25
  • In other words, a lifetime in a data structure _by definition_ means that the data structure refers to some data on stack above the structure. This is why the lifetime is "infective", if the reference is in a container, the container must also declare dependence on the data on the stack. Self-referential types allow a reference to something inside the container, without relying on an outside stack-managed value. – user4815162342 Jun 06 '23 at 06:44

0 Answers0