New to rust, I'm trying to build a state stack.
pub trait State {
fn tick(&mut self);
}
pub struct StateStack {
stack: Vec<Box<dyn State>>,
}
impl StateStack {
pub fn push(&mut self, state: Box<dyn State>) {
self.stack.push(state);
}
pub fn current(&mut self) -> &mut dyn State
{
&**self.stack.last_mut().expect("No state in stack")
}
}
When compiling, I get this error:
error[E0308]: mismatched types
--> src/main.rs:16:9
|
14 | pub fn current(&mut self) -> &mut dyn State
| -------------- expected `&mut dyn State` because of return type
15 | {
16 | &**self.stack.last_mut().expect("No state in stack")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
|
= note: expected mutable reference `&mut dyn State`
found reference `&(dyn State + 'static)`
I don't understand where this State + 'static'
come from, is this even the issue ?
I'm not sure where to begin to analyze this error. I think I get the deref chain right, but I feel I might be missing something here.
As a side question, I'm an OOP developper, and I'm not sure that what I'm doing is going the rustly way. Any other architecture to considere for state stack ?
The issue is you downgrade the mutable reference you got with last_mut
to an immutable reference when you use &**
. You need to instead take a mutable reference and that will solve the issue:
&mut **self.stack.last_mut().expect("No state in stack")
As for &(dyn State + 'static')
, you can mostly just ignore the 'static
. Anonymous traits (dyn Trait
) are not concrete types so they may not all share the same lifetime requirements. dyn State + 'static
indicates an anonymous State
trait which can survive for a lifetime of 'static
. 'static
just means that a lifetime in unconstrained and could be placed in a static context. Most types have a lifetime of 'static
so it does not get included in regular use. Some types with 'static
lifetimes would be primitives like u32
or f64
. Any dyn Trait
which does not include a lifetime gets an implicit 'static
.