Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

first-drop.html needs small clarification. #292

Open
rbarghou opened this issue Dec 4, 2023 · 0 comments
Open

first-drop.html needs small clarification. #292

rbarghou opened this issue Dec 4, 2023 · 0 comments

Comments

@rbarghou
Copy link

rbarghou commented Dec 4, 2023

I'm not skilled enough with Rust yet to understand the nature of the errors, but the code provided in the first-drop.html is no longer accurate.

I've followed the tutorial as closely as possible and checked as much as possible

I'm using rustc version 1.74.0

Here is my main.rs

use std::mem;

pub struct List {
    head: Link,
}

enum Link {
    Empty,
    More(Box<Node>),
}

struct Node {
    elem: i32,
    next: Link,
}


impl List {
    pub fn new() -> Self {
        List { head: Link::Empty }
    }

    pub fn push(&mut self, elem: i32) {
        let new_node = Box::new(Node {
            elem: elem,
            next: mem::replace(&mut self.head, Link::Empty)
        });
        self.head = Link::More(new_node);
    }

    pub fn pop(&mut self) -> Option<i32> {
        match mem::replace(&mut self.head, Link::Empty) {
            Link::Empty => None,
            Link::More(node) => {
                self.head = node.next;
                Some(node.elem)
            }
        }
    }
}

// impl Drop for List {
//     fn drop(&mut self) {
//         println!("Dropping List");
//     }
// }

impl Drop for List {
    fn drop(&mut self) {
        let mut cur_link = mem::replace(&mut self.head, Link::Empty);
        // `while let` == "do this thing until this pattern doesn't match"
        while let Link::More(mut boxed_node) = cur_link {
            cur_link = mem::replace(&mut boxed_node.next, Link::Empty);
            // boxed_node goes out of scope and gets dropped here;
            // but its Node's `next` field has been set to Link::Empty
            // so no unbounded recursion occurs.
        }
    }
}


impl Drop for Link {
    fn drop(&mut self) {
        match *self {
            Link::Empty => {}
            Link::More(ref mut boxed_node) => {
                boxed_node.drop();
            }
        }
    }
}

impl Drop for Box<Node> {
    fn drop(&mut self) {
        self.ptr.drop();
        deallocate(self.ptr);
    }
}

impl Drop for Node {
    fn drop(&mut self) {
        println!("Dropping Node");
        self.next.drop();
    }
}


fn main() {
    println!("Hello, world!");
}

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

    #[test]
    fn basics() {
        let mut list = List::new();
        assert_eq!(list.pop(), None);

        list.push(1);
        list.push(2);
        list.push(3);

        assert_eq!(list.pop(), Some(3));
        assert_eq!(list.pop(), Some(2));

        list.push(4);
        list.push(5);

        assert_eq!(list.pop(), Some(5));
        assert_eq!(list.pop(), Some(4));

        assert_eq!(list.pop(), Some(1));
        assert_eq!(list.pop(), None);
    }
}

Here is the output of the cargo build

➜  toomanylists git:(master) ✗ cargo build
   Compiling toomanylists v0.1.0 (/Users/ramseybarghouti/rust-too-many-lists/toomanylists)
error[E0119]: conflicting implementations of trait `Drop` for type `Box<Node>`
  --> src/main.rs:59:1
   |
59 | impl Drop for Box<Node> {
   | ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `alloc`:
           - impl<T, A> Drop for Box<T, A>
             where A: Allocator, T: ?Sized;

error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
  --> src/main.rs:59:15
   |
59 | impl Drop for Box<Node> {
   |               ^^^^^^^^^ must be a struct, enum, or union in the current crate

error[E0425]: cannot find function `deallocate` in this scope
  --> src/main.rs:62:9
   |
62 |         deallocate(self.ptr);
   |         ^^^^^^^^^^ not found in this scope

Some errors have detailed explanations: E0119, E0120, E0425.
For more information about an error, try `rustc --explain E0119`.

I think that what's intended in this tutorial is to only implement the Drop trait on the List Struct and not implement the Drop trait on List, Box<Node> and Node types, but I'm not sure. If that's the case I think this page simply needs some clarification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant