rustownershipownership-semantics

Cannot move out of borrowed content on enum containing a boxed trait object when deriving PartialEq


I'm trying to write an enum deriving PartialEq which contains a trait object which does so manually. I used the solution here in order to force implementors of Trait to write an equality method. This fails to compile:

trait Trait {
    fn partial_eq(&self, rhs: &Box<Trait>) -> bool;
}

impl PartialEq for Box<Trait> {
    fn eq(&self, rhs: &Box<Trait>) -> bool {
        self.partial_eq(rhs)
    }
}

#[derive(PartialEq)]
enum Enum {
    Trait(Box<Trait>),
}
error[E0507]: cannot move out of borrowed content
  --> src/main.rs:13:11
   |
13 |     Trait(Box<Trait>),
   |           ^^^^^^^^^^^ cannot move out of borrowed content

This only compiles when I manually impl PartialEq for Enum. Why is this the case?


Solution

  • Expanding the automatically-derived implementation of PartialEq presents a better error message:

    impl ::std::cmp::PartialEq for Enum {
        #[inline]
        fn eq(&self, __arg_0: &Enum) -> bool {
            match (&*self, &*__arg_0) {
                (&Enum::Trait(ref __self_0), &Enum::Trait(ref __arg_1_0)) => {
                    true && (*__self_0) == (*__arg_1_0)
                }
            }
        }
        #[inline]
        fn ne(&self, __arg_0: &Enum) -> bool {
            match (&*self, &*__arg_0) {
                (&Enum::Trait(ref __self_0), &Enum::Trait(ref __arg_1_0)) => {
                    false || (*__self_0) != (*__arg_1_0)
                }
            }
        }
    }
    
    error[E0507]: cannot move out of borrowed content
      --> src/main.rs:21:40
       |
    21 |                 true && (*__self_0) == (*__arg_1_0)
       |                                        ^^^^^^^^^^^^ cannot move out of borrowed content
    
    error[E0507]: cannot move out of borrowed content
      --> src/main.rs:29:41
       |
    29 |                 false || (*__self_0) != (*__arg_1_0)
       |                                         ^^^^^^^^^^^^ cannot move out of borrowed content
    

    This is tracked as Rust issues 31740 and 39128.

    You will likely need to implement PartialEq for this type yourself as well.