I am following Learning Rust With Entirely Too Many Linked Lists to write my first program in Rust. I changed the program to:
use std::mem;
#[derive(Debug)]
pub enum List {
Nil,
More(Box<Node>),
}
#[derive(Debug)]
pub struct Node {
val: i32,
next: List
}
impl List {
pub fn new() -> Self {
List::Nil
}
pub fn insert(&mut self, v : i32) {
let old_head = mem::replace(&mut *self, List::Nil);
let new_head = List::More(Box::new(Node { val : v, next: old_head}));
*self = new_head
}
pub fn remove(&mut self) -> Option<i32> {
match mem::replace(&mut *self, List::Nil) {
List::Nil => {
None
},
List::More(ref mut boxed_node) => {
let result = Some(boxed_node.val);
*self = mem::replace(&mut boxed_node.next, List::Nil);
result
}
}
}
}
impl Drop for List {
fn drop(&mut self) {
let mut head = mem::replace(&mut *self, List::Nil);
while let List::More(ref mut node) = mem::replace(&mut head, List::Nil) {
head = mem::replace(&mut node.next, List::Nil);
}
}
}
#[cfg(test)]
mod test {
use super::List;
#[test]
fn basics() {
let mut list = List::new();
list.insert(7);
assert_eq!(Some(7), list.remove());
assert_eq!(None, list.remove());
list.insert(1);
list.insert(2);
list.insert(3);
assert_eq!(Some(3), list.remove());
assert_eq!(Some(2), list.remove());
assert_eq!(Some(1), list.remove());
assert_eq!(None, list.remove());
}
#[test]
fn drop_long_list() {
let mut list = List::new();
for i in 1..100000 {
list.insert(i);
}
}
}
Both of my tests are failing with a stack overflow in drop
. Is it because of *self
in RHS?
I don't know what is happening with let mut head = mem::replace(&mut *self, List::Nil);
.
My understanding is:
- It sets
List::Nil
inself
. - Puts original value of
self
inhead
.
Is *self
doing something more?
I also tried this version of drop
:
impl Drop for List {
fn drop(&mut self) {
let mut head = mem::replace(self, List::Nil);
while let List::More(ref mut node) = mem::replace(&mut head, List::Nil) {
head = mem::replace(&mut node.next, List::Nil);
}
}
}
Another try:
impl Drop for List {
fn drop(&mut self) {
while true {
match self {
&mut List::Nil => break,
&mut List::More(ref mut node) => {
*self = mem::replace(&mut node.next, List::Nil)
}
}
}
}
}
error[E0506]: cannot assign to `*self` because it is borrowed
--> src\list.rs:48:21
|
47 | &mut List::More(ref mut node) => {
| ------------ borrow of `*self` occurs here
48 | *self = mem::replace(&mut node.next, List::Nil)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `*self` occurs here