{ wrap: &'a mut Op...">

"cannot derive a suitable lifetime for the template due to conflicting requirements" in the template `ref mut`

struct RefWrap<'a> { wrap: &'a mut Option<String>, } impl<'a> RefWrap<'a> { fn unwrap(&mut self) -> &'a mut String { match *self.wrap { Some(ref mut s) => s, None => panic!(), } } } 

( Playground )

As far as I understand, this code is correct (the returned link does have a 'a lifetime. But Rust produces the following error:

 error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements --> <anon>:8:18 | 8 | Some(ref mut s) => s, | ^^^^^^^^^ 

Using immutable links , it works without errors.

There was one similar question , but I am sure that this will not help in this case.

+6
source share
1 answer

It seems like the conflict is that the return value is:

  • Must be valid at least for the service life of 'a
  • You should not survive &mut self , which is just the lifetime of a function call.

If it were allowed, it would allow you to call it twice and get two &'a mut references to the same String content:

 let mut w = RefWrap { wrap: &mut s }; let ref1 = w.unwrap(); let ref2 = w.unwrap(); // two mutable references! 

The reason is because the way that Roorst talks about what is borrowed is to tie lives together, but here you directly declare that the lifetime of the return value is not related to &mut self , which means that it does not expand the loan - and then You can take a loan again using another call.

The solution here, to get the original representative lifetime, without risking a second &mut link that overlaps it, is to take self by value (move) so that it cannot be used again. The compiler is satisfied with this:

 impl<'a> RefWrap<'a> { fn unwrap(self) -> &'a mut String { match *self.wrap { Some(ref mut s) => s, None => panic!(), } } } 

( Playground )

+4
source

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


All Articles