summaryrefslogtreecommitdiffstats
path: root/tests/ui/derives/deriving-with-repr-packed-move-errors.rs
blob: ffeb02d78b84828dc384ddc08b5f709de840f48f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// 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(){
}