How to fix it: the value may contain links; add `static` tied to` T`

I still managed to cope with a lifelong problem, which I seem to be unable to solve on my own.

I have this trait

pub trait MiddlewareHandler: Clone { fn invoke (&self, req: &Request, res: &mut Response) -> bool { true } // we need this because otherwise clone() would be ambiguous fn clone_box(&self) -> Box<MiddlewareHandler> { box self.clone() as Box<MiddlewareHandler> } } impl MiddlewareHandler for fn (req: &Request, res: &mut Response) -> bool { fn invoke(&self, req: &Request, res: &mut Response) -> bool{ (*self).invoke(req, res) } } impl Clone for Box<MiddlewareHandler> { fn clone(&self) -> Box<MiddlewareHandler> { self.clone_box() } } 

What I am implementing for fn (req: &Request, res: &mut Response) -> bool in order to be able to simultaneously use lightweight functions and heavier MiddlewareHandler constructors.

I store them as a Vec<Box<MiddlewareHandler>>

 pub struct Middleware { handlers: Vec<Box<MiddlewareHandler>> } 

Now the problem is that the compiler is yelling at me right here:

  pub fn add<T: MiddlewareHandler> (&mut self, handler: T) { self.handlers.push(box handler); } 

It says:

 error: value may contain references; add `'static` bound to `T` self.handlers.push(box handler); 

The implementation should be very similar to the one used here:

https://github.com/iron/iron/blob/master/src/chain/stackchain.rs#L67

However, it seems I do not see the difference: - /

If someone wants to give me a hand, I moved the code in github to the static branch:

https://github.com/floor-org/floor/tree/static

+1
source share
2 answers

The problem is that to safely create an object with box features, the source object cannot have any lifetime parameters (other than static ), or the object itself must also respect this lifetime, which is not possible in general. To fix this:

 pub fn add<T: MiddlewareHandler + 'static> (&mut self, handler: T) { self.handlers.push(box handler); } 

He reads a little strange, but he says: " T needs to implement MiddlewareHandler and cannot contain links that do not have a static lifetime." This only works for static .

+1
source

The object object erases the internal data type, which means that it is not known just by looking at the Box<Trait> object object. In particular, any data lifetimes are also destroyed, therefore, the compiler cannot determine if / when the attribute object contains links to invalid data (i.e., the lifetime of any link has expired), therefore Rust currently ensures that any data in an attribute belonging to an object should never β€œexpire”. That is, there are no links in it (well, to be precise, any links are valid forever, i.e. 'static ).

This is expressed through the inline 'dash 'static :

 pub fn add<T: 'static + MiddlewareHandler>(... 

(This may change in the future, with native feature objects that may be limited to real-life, so storing links 'static will be safe.)

+1
source

Source: https://habr.com/ru/post/1200038/


All Articles