Given the following case:
code
struct Collection {
list: Vec<String>,
}
struct Similar<'c> {
list: Vec<&'c str>
}
impl Collection {
pub fn new() -> Self {
Self { list: Vec::new() }
}
pub fn add(&mut self, text: String) {
self.list.push(text);
}
pub fn try_add(&mut self, text: String) -> Result<(), Similar<'_>> {
let mut similar = Vec::new();
for item in self.list.iter() {
if item.contains(&text) {
similar.push(item.as_str());
}
}
// if any similar/same items found, return them
if !similar.is_empty() {
return Err(Similar {
list: similar
})
}
// otherwise, add right away
self.list.push(text);
Ok(())
}
}
Is there any way to avoid:
compiler error
error[E0502]: cannot borrow `self.list` as mutable because it is also borrowed as immutable
--> src/lib.rs:26:13
|
12 | pub fn try_add(&mut self, text: String) -> Result<(), Similar<'_>> {
| - let's call the lifetime of this reference `'1`
13 | let mut similar = Vec::new();
14 | for item in self.list.iter() {
| --------- immutable borrow occurs here
...
21 | return Err(Similar {
| ____________________-
22 | | list: similar
23 | | })
| |______________- returning this value requires that `self.list` is borrowed for `'1`
...
26 | self.list.push(text);
| ^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
For more information about this error, try `rustc --explain E0502`.
Without resorting to an index-based workaround via .iter().enumerate() or equivalent? It seems to be a rather straightforward reference flow for the borrow checker to handle, yet none of my attempts seem to have worked so far.
Including those to manually drop the similar itself, self.list.iter() saved to a separate variable beforehand, or manual 0..self.list.len() iteration with borrowing by index.