summaryrefslogtreecommitdiffstats
path: root/src/test/ui/union/union-borrow-move-parent-sibling.rs
blob: 83781c5e55092f04f64172d185261d1749abb57d (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
// revisions: mirunsafeck thirunsafeck
// [thirunsafeck]compile-flags: -Z thir-unsafeck

#![allow(unused)]

use std::ops::{Deref, DerefMut};
use std::mem::ManuallyDrop;

#[derive(Default)]
struct MockBox<T> {
    value: [T; 1],
}

impl<T> MockBox<T> {
    fn new(value: T) -> Self { MockBox { value: [value] } }
}

impl<T> Deref for MockBox<T> {
    type Target = T;
    fn deref(&self) -> &T { &self.value[0] }
}

impl<T> DerefMut for MockBox<T> {
    fn deref_mut(&mut self) -> &mut T { &mut self.value[0] }
}

#[derive(Default)]
struct MockVec<T> {
    value: [T; 0],
}

impl<T> MockVec<T> {
    fn new() -> Self { MockVec { value: [] } }
}

impl<T> Deref for MockVec<T> {
    type Target = [T];
    fn deref(&self) -> &[T] { &self.value }
}

impl<T> DerefMut for MockVec<T> {
    fn deref_mut(&mut self) -> &mut [T] { &mut self.value }
}


union U {
    x: ManuallyDrop<((MockVec<u8>, MockVec<u8>), MockVec<u8>)>,
    y: ManuallyDrop<MockBox<MockVec<u8>>>,
}

fn use_borrow<T>(_: &T) {}

unsafe fn parent_sibling_borrow() {
    let mut u = U { x: ManuallyDrop::new(((MockVec::new(), MockVec::new()), MockVec::new())) };
    let a = &mut (*u.x).0;
    let b = &u.y; //~ ERROR cannot borrow `u` (via `u.y`)
    use_borrow(a);
}

unsafe fn parent_sibling_move() {
    let u = U { x: ManuallyDrop::new(((MockVec::new(), MockVec::new()), MockVec::new())) };
    let a = u.x.0; //~ERROR cannot move out of dereference
    let a = u.x;
    let b = u.y; //~ ERROR use of moved value: `u`
}

unsafe fn grandparent_sibling_borrow() {
    let mut u = U { x: ManuallyDrop::new(((MockVec::new(), MockVec::new()), MockVec::new())) };
    let a = &mut ((*u.x).0).0;
    let b = &u.y; //~ ERROR cannot borrow `u` (via `u.y`)
    use_borrow(a);
}

unsafe fn grandparent_sibling_move() {
    let u = U { x: ManuallyDrop::new(((MockVec::new(), MockVec::new()), MockVec::new())) };
    let a = (u.x.0).0; //~ERROR cannot move out of dereference
    let a = u.x;
    let b = u.y; //~ ERROR use of moved value: `u`
}

unsafe fn deref_sibling_borrow() {
    let mut u = U { y: ManuallyDrop::new(MockBox::default()) };
    let a = &mut *u.y;
    let b = &u.x; //~ ERROR cannot borrow `u` (via `u.x`)
    use_borrow(a);
}

unsafe fn deref_sibling_move() {
    let u = U { x: ManuallyDrop::new(((MockVec::new(), MockVec::new()), MockVec::new())) };
    // No way to test deref-move without Box in union
    // let a = *u.y;
    // let b = u.x; ERROR use of moved value: `u`
}


fn main() {}