summaryrefslogtreecommitdiffstats
path: root/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs
blob: 6b0b09c98945c0edf85cba263dcb1d485805eacb (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// run-pass
// check raw fat pointer ops

use std::mem;

fn assert_inorder<T: PartialEq + PartialOrd>(a: &[T]) {
    for i in 0..a.len() {
        for j in 0..a.len() {
            if i < j {
                assert!(a[i] < a[j]);
                assert!(a[i] <= a[j]);
                assert!(!(a[i] == a[j]));
                assert!(a[i] != a[j]);
                assert!(!(a[i] >= a[j]));
                assert!(!(a[i] > a[j]));
            } else if i == j {
                assert!(!(a[i] < a[j]));
                assert!(a[i] <= a[j]);
                assert!(a[i] == a[j]);
                assert!(!(a[i] != a[j]));
                assert!(a[i] >= a[j]);
                assert!(!(a[i] > a[j]));
            } else {
                assert!(!(a[i] < a[j]));
                assert!(!(a[i] <= a[j]));
                assert!(!(a[i] == a[j]));
                assert!(a[i] != a[j]);
                assert!(a[i] >= a[j]);
                assert!(a[i] > a[j]);
            }
        }
    }
}

trait Foo { fn foo(&self) -> usize; }
impl<T> Foo for T {
    fn foo(&self) -> usize {
        mem::size_of::<T>()
    }
}

#[allow(unused_tuple_struct_fields)]
struct S<T:?Sized>(u32, T);

fn main() {
    let mut array = [0,1,2,3,4];
    let mut array2 = [5,6,7,8,9];

    // fat ptr comparison: addr then extra

    // check ordering for arrays
    let mut ptrs: Vec<*const [u8]> = vec![
        &array[0..0], &array[0..1], &array, &array[1..]
    ];

    let array_addr = &array as *const [u8] as *const u8 as usize;
    let array2_addr = &array2 as *const [u8] as *const u8 as usize;
    if array2_addr < array_addr {
        ptrs.insert(0, &array2);
    } else {
        ptrs.push(&array2);
    }
    assert_inorder(&ptrs);

    // check ordering for mut arrays
    let mut ptrs: Vec<*mut [u8]> = vec![
        &mut array[0..0], &mut array[0..1], &mut array, &mut array[1..]
    ];

    let array_addr = &mut array as *mut [u8] as *mut u8 as usize;
    let array2_addr = &mut array2 as *mut [u8] as *mut u8 as usize;
    if array2_addr < array_addr {
        ptrs.insert(0, &mut array2);
    } else {
        ptrs.push(&mut array2);
    }
    assert_inorder(&ptrs);

    let mut u8_ = (0u8, 1u8);
    let mut u32_ = (4u32, 5u32);

    // check ordering for ptrs
    let buf: &mut [*const dyn Foo] = &mut [
        &u8_, &u8_.0,
        &u32_, &u32_.0,
    ];
    buf.sort_by(|u,v| {
        let u : [*const (); 2] = unsafe { mem::transmute(*u) };
        let v : [*const (); 2] = unsafe { mem::transmute(*v) };
        u.cmp(&v)
    });
    assert_inorder(buf);

    // check ordering for mut ptrs
    let buf: &mut [*mut dyn Foo] = &mut [
        &mut u8_, &mut u8_.0,
        &mut u32_, &mut u32_.0,
    ];
    buf.sort_by(|u,v| {
        let u : [*const (); 2] = unsafe { mem::transmute(*u) };
        let v : [*const (); 2] = unsafe { mem::transmute(*v) };
        u.cmp(&v)
    });
    assert_inorder(buf);

    // check ordering for structs containing arrays
    let ss: (S<[u8; 2]>,
             S<[u8; 3]>,
             S<[u8; 2]>) = (
        S(7, [8, 9]),
        S(10, [11, 12, 13]),
        S(4, [5, 6])
    );
    assert_inorder(&[
        &ss.0 as *const S<[u8]>,
        &ss.1 as *const S<[u8]>,
        &ss.2 as *const S<[u8]>
    ]);
}