A Issue about borrowed check

I get a Issue about borrowed check, as follows code

    fn remove_node(&mut self, val: i32) {
        let mut current_node = &mut self.head;
        while let Some(node) = current_node {
            if node.val == val {  
                *current_node = node.next.take();
                break;
            } else {
                current_node = &mut node.next;
            }
        }
    }

I get a error message(" `*current_node` is assigned to here but it was already borrowed, borrow later used here"). if remove else block code or if block code, i will don't get error. I don't know why.

these all code: Rust Playground

Looks like NLL Problem Case #3.

You can read more about it in this crate. Sometimes it can be worked around (expand the Non-unsafe section), though I don't have time just now to try to apply it to your case myself. Or the crate itself may work for you.

1 Like

Thanks your answer. I now know the cause of the problem. use the borrowed value from current_node later, so don't allow to update it. I now think how to resolve problem with a better plan. but no result yet. :sweat_smile:

Here's one possibility (untested).

Here’s the minimal fix I could come up with

    fn remove_node(&mut self, val: i32) {
        let mut crruent_node = &mut self.head;
        while let Some(node) = crruent_node {
            if node.val == val {    
                *crruent_node = node.next.take();
                break;
            } else {
-               crruent_node = &mut node.next;
+               crruent_node = &mut crruent_node.as_mut().unwrap().next;
            }
        }
    }
1 Like

If this is just for learning Rust, of course use one of the proposed solutions. But if you really need linked lists: you do know that the stdlib has a LinkedList type, right? See LinkedList in std::collections - Rust.

#![feature(drain_filter)]

use std::collections::LinkedList;

fn remove_all_equal_to<T>(lst: &mut LinkedList<T>, elt: &T)
where T: Eq
{
    lst.drain_filter(|list_elt: &mut T| list_elt == elt);
}

fn remove_first_equal_to<T>(lst: &mut LinkedList<T>, elt: &T)
where T: Eq
{
    let mut found = false;
    lst.drain_filter(|list_elt: &mut T| {
        if !found && list_elt == elt {
            found = true;
            true
        } else {
            false
        }
    });
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_remove_all_equal_to() {
        let mut lst : LinkedList<i32> = [1, 2, 3, 2, 3].into();
        remove_all_equal_to(&mut lst, &2);
        assert_eq!(lst, [1, 3, 3].into());
    }

    #[test]
    fn test_remove_first_equal_to() {
        let mut lst : LinkedList<i32> = [1, 2, 3, 2, 3].into();
        remove_first_equal_to(&mut lst, &2);
        assert_eq!(lst, [1, 3, 2, 3].into());
    }
}

good

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.