Confused about { Rc::clone(&n.borrow() } for RefCell>

⚓ rust    📅 2025-05-14    👤 surdeus    👁️ 3      

surdeus

use std::cell::RefCell;
use std::rc::Rc;

#[derive(Debug)]
enum ConsList {
    Val(RefCell<i32>, RefCell<Rc<ConsList>>),
    Nil,
}

impl ConsList {
    fn new() -> Rc<ConsList> {
        Rc::new(ConsList::Nil)
    }
    
    fn new_val(val: i32) -> Rc<ConsList> {
        Rc::new(ConsList::Val(RefCell::new(val), RefCell::new(ConsList::new())))
    }
    
    fn new_val_next(val: i32, next: &Rc<ConsList>) -> Rc<ConsList> {
        Rc::new(
            ConsList::Val(
                RefCell::new(val),
                RefCell::new(Rc::clone(next))
            ) 
       )
    }
}

fn main() {

    let l1 = ConsList::new_val(4);
    let l2 = ConsList::new_val_next(5, &l1);
    let l3 = ConsList::new_val_next(6, &l2);
    let l4 = ConsList::new_val_next(7, &l3);
    
    
    let mut ptr = Rc::clone(&l4); 
    
    while let ConsList::Val(v, n) = &*ptr {
        println!("v: {}", v.borrow());
        // ptr = Rc::clone(&n.borrow());
        ptr = { Rc::clone(&n.borrow()) }
    }
}

(Playground)

Output:

v: 7
v: 6
v: 5
v: 4

Errors:

   Compiling playground v0.0.1 (/playground)
warning: unnecessary braces around assigned value
  --> src/main.rs:42:15
   |
42 |         ptr = { Rc::clone(&n.borrow()) }
   |               ^^                      ^^
   |
   = note: `#[warn(unused_braces)]` on by default
help: remove these braces
   |
42 -         ptr = { Rc::clone(&n.borrow()) }
42 +         ptr = Rc::clone(&n.borrow())
   |

warning: `playground` (bin "playground") generated 1 warning (run `cargo fix --bin "playground"` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.64s
     Running `target/debug/playground`

Why does:

ptr = Rc::clone(&n.borrow());

The above does not compile,

But the snippet below:

ptr ={ Rc::clone(&n.borrow()) };

Compiles and works as intended?

2 posts - 2 participants

Read full topic

🏷️ rust_feed