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.
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
Here is the output of the
cargo build
I think that what's intended in this tutorial is to only implement the
Drop
trait on theList
Struct and not implement theDrop
trait onList
,Box<Node>
andNode
types, but I'm not sure. If that's the case I think this page simply needs some clarification.