Error creating LinkedList

Can someone help why is this error coming? As just 10min before when I first wrote it, it worked just fine. It suddenly started throwing errors. I am unable to understand this behavior of the rust-analyzer. Do I need to explicitly define the type?

Any help is appreciated.
Thanks.

use std::{
    borrow::{Borrow, BorrowMut},
    cell::{Ref, RefCell},
    rc::Rc,
};

pub struct ListNode<T: Copy + Eq> {
    pub data: T,
    pub next: Option<Rc<RefCell<ListNode<T>>>>,
}

impl<T: Copy + Eq> ListNode<T> {
    pub fn new(data: T) -> Self {
        ListNode { data, next: None }
    }
}

impl<T: Copy + Eq> From<ListNode<T>> for Option<Rc<RefCell<ListNode<T>>>> {
    fn from(node: ListNode<T>) -> Self {
        Some(Rc::new(RefCell::new(node)))
    }
}

type ListNodePtr<T> = Rc<RefCell<ListNode<T>>>;

pub struct List<T: Copy + Eq> {
    pub head: Option<ListNodePtr<T>>,
    pub tail: Option<ListNodePtr<T>>,
    pub capacity: i32,
}

impl<T: Copy + Eq> List<T> {
    pub fn new() -> Self {
        Self {
            head: None,
            tail: None,
            capacity: 0,
        }
    }

    pub fn push(&mut self, value: T) {
        let node = ListNode::new(value);
        // push in next of tail
        match &mut self.tail.take() {
            None => {
                self.head = node.into();
                self.tail = self.head.clone();
            }
            Some(tail) => {
                self.tail = node.into();
                tail.borrow_mut().next = self.tail.clone();
            }
        }
        self.capacity += 1;
    }

    // check if value is present
    pub fn search(&self, value: T) -> bool {
        for val in self.iter() {
            if value.eq(&val) {
                return true;
            }
        }
        false
    }

    pub fn remove(&mut self, value: T) -> Option<T> {
        // search the value and delete
        todo!("to be done");
    }

    //Iterator
    fn iter(&self) -> ListIterator<T> {
        ListIterator {
            current: self.head.clone(),
        }
    }
}

impl<T: Copy + Eq> Default for List<T> {
    fn default() -> Self {
        Self::new()
    }
}

struct ListIterator<T: Copy + Eq> {
    current: Option<ListNodePtr<T>>,
}

impl<T: Copy + Eq> Iterator for ListIterator<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        let current_opt = self.current.take();
        match current_opt {
            Some(current_ref) => {
                let current_borrowed = current_ref.borrow();
                self.current = current_borrowed.next.clone();
                Some(current_borrowed.data)
            }
            None => None
        }
    }
}

fn main() {
    let mut list = List::<i32>::new();
    list.push(23);
    list.push(13);
    list.push(4);
    list.push(1);
    list.push(9);
    list.push(6);
    list.push(2);

    for val in list.iter() {
        print!("{} ", val);
    }
    println!();

    list.iter().for_each(|val| {
        print!("{} ", val);
    });
    println!();

    // searching an element
    let check = list.search(6);
    println!("is element 6 present in list? = {}", check);
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
warning: unused import: `Ref`
 --> src/main.rs:3:12
  |
3 |     cell::{Ref, RefCell},
  |            ^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error[E0609]: no field `next` on type `&mut Rc<RefCell<ListNode<T>>>`
  --> src/main.rs:51:35
   |
51 |                 tail.borrow_mut().next = self.tail.clone();
   |                                   ^^^^ unknown field

error[E0282]: type annotations needed for `&Borrowed`
  --> src/main.rs:97:21
   |
97 |                 let current_borrowed = current_ref.borrow();
   |                     ^^^^^^^^^^^^^^^^
98 |                 self.current = current_borrowed.next.clone();
   |                                --------------------- type must be known at this point
   |
help: consider giving `current_borrowed` an explicit type, where the type for type parameter `Borrowed` is specified
   |
97 |                 let current_borrowed: &Borrowed = current_ref.borrow();
   |                                     +++++++++++

error[E0609]: no field `next` on type `&_`
  --> src/main.rs:98:49
   |
98 |                 self.current = current_borrowed.next.clone();
   |                                                 ^^^^ unknown field

Some errors have detailed explanations: E0282, E0609.
For more information about an error, try `rustc --explain E0282`.
warning: `playground` (bin "playground") generated 1 warning
error: could not compile `playground` (bin "playground") due to 3 previous errors; 1 warning emitted

Your errors most likely started when you added the imports of Borrow and BorrowMut. Where you used the RefCell::borrow and RefCell::borrow_mut methods before, you are now using <RefCell<T> as Borrow<RefCell<T>>>::borrow and <RefCell<T> as BorrowMut<RefCell<T>>>::borrow_mut methods due to Borrow and BorrowMut being in scope.

3 Likes

If you need to have the Borrow traits imported you can fix this with fully qualified syntax:

RefCell::borrow_mut(tail).next

2 Likes

My advice is don't import the Borrow / BorrowMut traits, especially if you're using RefCell. You generally don't need them outside the context of keyed data structures like HashMap and BTreeMap, every type implements them which makes many things ambiguous, and the method names conflict with those of RefCell to boot.

(Probably some well-intentioned but erroneous compiler error/hint suggested importing them when you tried to .borrow() a non-RefCell or the like.)

2 Likes

Thanks, I donot have much knowledge about Borrow/BorrowMut traits, I think I accidentally imported them on suggestion of the rust-analyzer in VSCode. Thanks though, I'll read more upon them.

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.