functionrustborrow-checker

Call Box<dyn FnMut> as struct field


I have a struct called UpgradeProperties that takes a Box<dyn FnMut(&mut Self)> as a field. However, when I try to create a function to call it I get an error.

Relevant Code:

pub struct UpgradeProperties {
    pub name: String,
    pub description: String,
    pub cost: u32,
    pub cost_increase: u8,
    pub icon: Texture2D,
    pub current: f32,
    pub buy: Box<dyn FnMut(&mut Self)>,
}

impl UpgradeProperties {
    pub fn call_buy(&mut self) {
        (self.buy)(self);
    }
}
buy: Box::new(move |s| {
    s.cost *= s.cost_increase as u32;
    s.current += 1.0;
}),

Result:

error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/upgrade.rs:22:20
   |
22 |         (self.buy)(self);
   |         ---------- ^^^^ second mutable borrow occurs here
   |         |
   |         first mutable borrow occurs here
   |         first borrow later used by call

For more information about this error, try `rustc --explain E0499`.

Note: I want to have multiple instances with different "buy" functions


Solution

  • Note: I solved this by changing my code to be like this:

    buy: (|s: &mut UpgradeProperties| {
    s.cost += s.cost_increase as u32;
    s.cost_increase += 1;
    s.current += 10.0;
    }),
    
    pub struct UpgradeProperties {
        pub name: String,
        pub description: String,
        pub cost: u32,
        pub cost_increase: u8,
        pub icon: Texture2D,
        pub current: f32,
        pub buy: fn(&mut Self),
    }