1

I have a rust-playground link here, and the full code for my basic example is:

trait Obj {
    fn hit(&self, t0: f64, t1: f64) -> bool;
}

struct Leaf {
    data: f64,
}

impl Obj for Leaf {
    fn hit(&self, t0: f64, t1: f64) -> bool { return t0 < self.data && self.data < t1 }
}

struct Node<'a> {
    data: f64,
    left: &'a Box<dyn Obj>,
    right: &'a Box<dyn Obj>,
}

impl<'a> Obj for Node<'a> {
    fn hit(&self, t0: f64, t1: f64) -> bool {
        self.left.hit(t0, t1) || self.right.hit(t0, t1)
    }
}

impl<'a> Node<'a> {
    fn new(tmin: f64, tmax: f64) -> Self {
        let mid = (tmin + tmax) / 2.;
        if tmax - tmin < 1. {
            return Self { data: tmin, left: &Box::new(Leaf {data: tmin }), right: &Box::new(Leaf {data :tmax} ) };
        }
        let left = Node::new(tmin, mid);
        let right = Node::new(mid, tmax);
        Self {data: tmin, left: &Box::new(left), right: &Box::new(right) }
    }
}

fn main() {
    let node = Node::new(0., 100.);
    ()
}

It's a contrived example, but it gives the same compiler errors I get in my real version. In the constructor for Node, I get the following errors:

error[E0308]: mismatched types
  --> src/main.rs:29:83
   |
29 |             return Self { data: tmin, left: &Box::new(Leaf {data: tmin }), right: &Box::new(Leaf {data :tmax} ) };
   |                                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Obj`, found struct `Leaf`
   |
   = note: expected reference `&'a std::boxed::Box<(dyn Obj + 'static)>`
              found reference `&std::boxed::Box<Leaf>`

error[E0308]: mismatched types
  --> src/main.rs:33:33
   |
33 |         Self {data: tmin, left: &Box::new(left), right: &Box::new(right) }
   |                                 ^^^^^^^^^^^^^^^ expected trait object `dyn Obj`, found struct `Node`
   |
   = note: expected reference `&'a std::boxed::Box<(dyn Obj + 'static)>`
              found reference `&std::boxed::Box<Node<'_>>`

Why do I get these errors? Both Leaf and Node implement Obj, and my understanding is that they could both be of type dyn Obj. I think it has something to do with lifetimes, but I can't think of how to fix this. What's the proper way of making this binary tree structure in Rust?

2

1 Answer 1

3

Box<..> is an owned type, so it can live on its own, been moved without a lifetime track. In your example you simply can remove all of the references and a lifetime, so the struct definition becomes:

struct Node {
    data: f64,
    left: Box<dyn Obj>,
    right: Box<dyn Obj>,
}

Here a full example.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.