Rust iterator with muatble reference keeps blocking other references after being used

35 views Asked by At

I am giving a mutable reference of a Vec to an Iterator, so it can add Elements to it while just keeping an index of the Element. Thus after the Iterator being "used" shouldn't then the Vec be able to be referenced again?

(Here a link to a Rust playground example)

struct MyElement{
    category_index: usize,
    ...
}

impl MyElement{
    fn iter_from_src<'a>(source: &'a str, categories: &'a mut Vec<&'a str>)
      -> impl Iterator< Item = MyElement > {
        ...
        std::iter::from_fn(move || -> Option<MyElement> {
            ... //some iterator logic
            let category = find_category_in_source(source);
            if let Some(index) = categories.iter().position(|c| *c == category) {
                //no reference of categories is given to MyElement exept of the index
                Some( MyElement{ category_index: index, ... } )
            } else {
                let index = categories.len();
                // the only mutable usage of categories
                categories.push(category);

                Some( MyElement{ category_index: index, ... } )
            }

        })
    }
}

fn main() {
    let source: String = get_source();
    let mut categories = Vec::with_capacity(32);
    let mut elements = Vec::with_capacity(1024);
    
    for element in MyElement::iter_from_src(&source, &mut categories) {
        elements.push(element);
    }

    ...
    // error occurs here
    println!("{categories:#?}");

}

and there is no difference in using

let elements = MyElement::iter_from_src(&source, &mut categories).collect();

instead of the for-loop.

Eitherway the compiler Refuses:

error[E0502]: cannot borrow `categories` as immutable because it is also borrowed as mutable
  --> src/main.rs:81:16
   |
74 |     for element in MyElement::iter_from_src(&source, &mut categories) {
   |                                                      --------------- mutable borrow occurs here
...
81 |     println!("{categories:#?}");
   |                ^^^^^^^^^^
   |                |
   |                immutable borrow occurs here
   |                mutable borrow later used here

I am pretty new to rust so it can just be me understanding a concept wrong.

Still: Why does this throw an error?

And how can it be made possible, that the categories can not be referenced while the Iterator exists though they can afterwards?

0

There are 0 answers