1

EDIT: Updated my code snippet to better capture the issue

So I'm running into an issue getting the following scenario to work.

fn main() {
    print!("testing");
    let mut game = MyGame {
      player: Player {  },
      camera: Camera::new()  
    };
    game.camera.set_focus_target(Some(&game.player));
}

struct MyGame<'a> {
    player: Player,
    camera: Camera<'a>,
}

impl<'a> MyGame<'a> {
    pub fn foo(&mut self) {
        self.camera.set_focus_target(Some(&self.player));
    }
}

pub struct Player {
    
}


impl CameraFocusable for Player {
    fn get_focus_position(&self) -> [f32; 2] {
        [0.0, 0.0]
    }
}

impl<'a> Camera<'a> {
    pub fn new() -> Camera<'a> {
        Self { 
            focus: [0.0, 0.0],
            focus_target: None
        }
    }

    pub fn set_focus(&mut self, focus: [f32; 2]) {
        self.focus = focus;
    }

    pub fn set_focus_target(&mut self, focus_target: Option<&'a dyn CameraFocusable>) {
        self.focus_target = focus_target;
    }

}

pub struct Camera<'a> {
    focus: [f32; 2],
    focus_target: Option<&'a dyn CameraFocusable>,
}

pub trait CameraFocusable {
    fn get_focus_position(&self) -> [f32; 2];
}

This line

self.camera.set_focus_target(Some(&self.player));

causes this error:

cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
expected `&mut Camera<'_>`
   found `&mut Camera<'a>`rustcE0495
main.rs(89, 15): first, the lifetime cannot outlive the anonymous lifetime defined here...
main.rs(90, 43): ...so that reference does not outlive borrowed content
main.rs(88, 6): but, the lifetime must be valid for the lifetime `'a` as defined here...
main.rs(90, 21): ...so that the types are compatible

Any idea how to get this approach to work? My desire is that Camera can have a reference to a struct that implements CameraFocusable that it can use to focus on.

Is this an anti-pattern in rust? Ultimately, this should be accomplished relatively simply, right?

Vignesh K
  • 13
  • 4
  • Your `Camera` struct doesn't have a `focus_target` field, or anything that uses its `'a` lifetime... Create an [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) – Colonel Thirty Two Jul 26 '22 at 18:12
  • I'm guessing it's complaining about not having `<'a>` on your `Camera` in the `MyGame` struct, but I can't reproduce your problem with the snippets you gave. – Jeremy Meadows Jul 26 '22 at 18:30
  • Hey guys, sorry, I updated my code to better explain the scenario and the issue. – Vignesh K Jul 26 '22 at 19:27
  • 1
    Changing `pub fn foo(&mut self)` to `pub fn foo(&'a mut self)` works with this [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2596167f16e857f4724fe5444599bb9d) – PitaJ Jul 26 '22 at 19:52
  • @PitaJ Now try doing _anything_ with `MyGame` after you've called `foo`… – Jmb Jul 26 '22 at 20:42
  • Certainly, it may not be a solution that works for OP. – PitaJ Jul 26 '22 at 21:11
  • @PitaJ better say it's a "solution" that never works – Jmb Jul 26 '22 at 21:25
  • @PitaJ I can't quite do that since the function foo is part of a trait on an external package( sorry, I should have included that). – Vignesh K Jul 26 '22 at 22:49
  • @Jmb Am I trying to do something that shouldn't/can't be done in Rust? I see your link, but I don't think I understand it well enough to know if it applies to my scenario. – Vignesh K Jul 26 '22 at 22:49
  • 1
    @VigneshK it applies to your scenario because you're trying to make `game.camera.focus_target` contain a reference to another part of `game` (specifically `game.player`). It can be solved with `Rc` or `Arc>` as in [this answer](https://stackoverflow.com/a/70776273/5397009) ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=11d2729109898ed37f7c7a31e151fd21)) – Jmb Jul 27 '22 at 06:40

0 Answers0