Aeledfyr / deepsize

A rust crate to find the total size of an object, on the stack and on the heap
MIT License
103 stars 19 forks source link

deep_size_of_children() resolves to different implementations depending on which impl blocks deep_size_of() is called in #37

Open wanyingluo opened 1 year ago

wanyingluo commented 1 year ago

Hello, I ran into the following surprising behavior and wonder if it's intentional.

trait MyTrait {
    fn run(&mut self);
}
#[derive(deepsize::DeepSizeOf, Default)]
struct State {
    data: Vec<String>,
}
impl State {
    fn print_deepsize(&self) {
        println!(
            "[deepsize in impl block] {:p} {}",
            self,
            self.deep_size_of()
        );
    }
}
impl MyTrait for State {
    fn run(&mut self) {
        self.data.push(String::from("foobar"));
        println!(
            "[deepsize in impl XX for YY block] {:p} {}",
            self,
            self.deep_size_of()
        );
        self.print_deepsize();
    }
}
fn main() {
    let mut state = State::default();
    state.run();
}

Running this produces the following output:

[deepsize in impl XX for YY block] 0x7fff18ea0990 8
[deepsize in impl block] 0x7fff18ea0990 126

That's surprising. I expect both calls to deep_size_of() return the same result. It seems both calls resolve to the same deep_size_of() in the DeepSize library. However, the deep_size_of_children() call in it resolves to different ones. It resolves to the derived one when deep_size_of() is called in impl State, but resolves to the following one when when deep_size_of() is called in impl MyTrait for State.

impl<T> DeepSizeOf for &mut T
where
    T: DeepSizeOf +?Sized,
{
    fn deep_size_of_children(&self, _context: &mut Context) -> usize {
        0
    }
} 

Is this intended behavior or a bug in the library?