Any rules about Clone trait and deep copying I missed?


#1

Hi all,

I am using Rust for a project. I met a weird bug in my code that I couldn’t figure out.

  • I have a fairly complicated struct, say struct Foo, and let it derive Clone trait.
  • Foo has the ownership of some of its fields such as Box<Bar>, Bar, Vec<Bar>, HashMap<usize, Bar>, MyEnum::Var(Bar), but shares some fields by Arc<T> (which does not quite matter in this case).
  • Some fields is locked with RwLock/Mutex, so that I have to implement Clone trait. I acquire the lock, and clone its inner data, and wrap it in a new lock.
  • Bar also owns some of its fields (say Baz) through the same way. This chain goes on for several layers, and all the structs (Bar, Baz, etc) have Clone trait, and owned by Foo.

When I create Foo, I immediately clone the struct as a copy and hope to keep it as original data. I only make mutations on one copy, and leave the other copy unchanged. However, I end up finding that Baz is changed in both copies. In my understanding, derived Clone trait on structs, HashMap and Vec does deep copying, and if Foo actually owns (does not share) its fields, cloning Foo will also cloning its fields (and the fields of its fields). I have no idea why it ends up as both copies get modified. I would appreciate any input.

Thanks a lot.


#2

Everything except Rc and Arc should do a deep copy when you call clone. Box, Vec, and HashMap definitely do.

Can you give a playpen example? play.rust-lang.org.