| // Check that deriving builtin traits for a packed struct with |
| // non-Copy fields emits move errors along with an additional |
| // diagnostic note explaining the reason |
| // See issue #117406 |
| |
| use std::fmt::{Debug, Formatter, Result}; |
| use std::cmp::Ordering; |
| |
| // Packed + derives: additional diagnostic should be emitted |
| // for each of Debug, PartialEq and PartialOrd |
| #[repr(packed)] |
| #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] |
| struct StructA(String); |
| //~^ ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `other` which is behind a shared reference |
| //~| ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `other` which is behind a shared reference |
| //~| ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `other` which is behind a shared reference |
| //~| ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `self` which is behind a shared reference |
| |
| |
| // Unrelated impl: additinal diagnostic should NOT be emitted |
| impl StructA { |
| fn fmt(&self) -> String { |
| self.0 //~ ERROR: cannot move out of `self` which is behind a shared reference |
| } |
| } |
| |
| // Packed + manual impls: additional diagnostic should NOT be emitted |
| #[repr(packed)] |
| struct StructB(String); |
| |
| impl Debug for StructB { |
| fn fmt(&self, f: &mut Formatter) -> Result { |
| let x = &{ self.0 }; //~ ERROR: cannot move out of `self` which is behind a shared reference |
| write!(f, "{}", x) |
| } |
| } |
| |
| impl PartialEq for StructB { |
| fn eq(&self, other: &StructB) -> bool { |
| ({ self.0 }) == ({ other.0 }) |
| //~^ ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `other` which is behind a shared reference |
| } |
| } |
| |
| impl PartialOrd for StructB { |
| fn partial_cmp(&self, other: &StructB) -> Option<Ordering> { |
| PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 }) |
| //~^ ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `other` which is behind a shared reference |
| } |
| } |
| |
| // NOT packed + derives: additinal diagnostic should NOT be emitted |
| #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)] |
| struct StructC(String); |
| |
| // NOT packed + manual impls: additinal dignostic should NOT be emitted |
| struct StructD(String); |
| |
| impl Debug for StructD { |
| fn fmt(&self, f: &mut Formatter) -> Result { |
| let x = &{ self.0 }; //~ ERROR: cannot move out of `self` which is behind a shared reference |
| write!(f, "{}", x) |
| } |
| } |
| |
| impl PartialEq for StructD { |
| fn eq(&self, other: &StructD) -> bool { |
| ({ self.0 }) == ({ other.0 }) |
| //~^ ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `other` which is behind a shared reference |
| } |
| } |
| |
| impl PartialOrd for StructD { |
| fn partial_cmp(&self, other: &StructD) -> Option<Ordering> { |
| PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 }) |
| //~^ ERROR: cannot move out of `self` which is behind a shared reference |
| //~| ERROR: cannot move out of `other` which is behind a shared reference |
| } |
| } |
| |
| // Packed + derives but the move is outside of a derive |
| // expansion: additinal diagnostic should NOT be emitted |
| fn func(arg: &StructA) -> String { |
| arg.0 //~ ERROR: cannot move out of `arg` which is behind a shared reference |
| } |
| |
| fn main(){ |
| } |