summaryrefslogtreecommitdiffstats
path: root/src/test/ui/mir/mir_raw_fat_ptr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/mir/mir_raw_fat_ptr.rs')
-rw-r--r--src/test/ui/mir/mir_raw_fat_ptr.rs216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/test/ui/mir/mir_raw_fat_ptr.rs b/src/test/ui/mir/mir_raw_fat_ptr.rs
new file mode 100644
index 000000000..6aceefbe7
--- /dev/null
+++ b/src/test/ui/mir/mir_raw_fat_ptr.rs
@@ -0,0 +1,216 @@
+// run-pass
+// check raw fat pointer ops in mir
+// FIXME: please improve this when we get monomorphization support
+#![feature(raw_ref_op)]
+
+use std::mem;
+
+#[derive(Debug, PartialEq, Eq)]
+struct ComparisonResults {
+ lt: bool,
+ le: bool,
+ gt: bool,
+ ge: bool,
+ eq: bool,
+ ne: bool
+}
+
+const LT: ComparisonResults = ComparisonResults {
+ lt: true,
+ le: true,
+ gt: false,
+ ge: false,
+ eq: false,
+ ne: true
+};
+
+const EQ: ComparisonResults = ComparisonResults {
+ lt: false,
+ le: true,
+ gt: false,
+ ge: true,
+ eq: true,
+ ne: false
+};
+
+const GT: ComparisonResults = ComparisonResults {
+ lt: false,
+ le: false,
+ gt: true,
+ ge: true,
+ eq: false,
+ ne: true
+};
+
+fn compare_su8(a: *const S<[u8]>, b: *const S<[u8]>) -> ComparisonResults {
+ ComparisonResults {
+ lt: a < b,
+ le: a <= b,
+ gt: a > b,
+ ge: a >= b,
+ eq: a == b,
+ ne: a != b
+ }
+}
+
+fn compare_au8(a: *const [u8], b: *const [u8]) -> ComparisonResults {
+ ComparisonResults {
+ lt: a < b,
+ le: a <= b,
+ gt: a > b,
+ ge: a >= b,
+ eq: a == b,
+ ne: a != b
+ }
+}
+
+fn compare_foo<'a>(a: *const (dyn Foo+'a), b: *const (dyn Foo+'a)) -> ComparisonResults {
+ ComparisonResults {
+ lt: a < b,
+ le: a <= b,
+ gt: a > b,
+ ge: a >= b,
+ eq: a == b,
+ ne: a != b
+ }
+}
+
+fn simple_eq<'a>(a: *const (dyn Foo+'a), b: *const (dyn Foo+'a)) -> bool {
+ let result = a == b;
+ result
+}
+
+fn assert_inorder<T: Copy>(a: &[T],
+ compare: fn(T, T) -> ComparisonResults) {
+ for i in 0..a.len() {
+ for j in 0..a.len() {
+ let cres = compare(a[i], a[j]);
+ if i < j {
+ assert_eq!(cres, LT);
+ } else if i == j {
+ assert_eq!(cres, EQ);
+ } else {
+ assert_eq!(cres, GT);
+ }
+ }
+ }
+}
+
+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_ref() {
+ let array = [0,1,2,3,4];
+ let 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, compare_au8);
+
+ let u8_ = (0u8, 1u8);
+ let 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, compare_foo);
+
+ // 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]>
+ ], compare_su8);
+
+ assert!(simple_eq(&0u8 as *const _, &0u8 as *const _));
+ assert!(!simple_eq(&0u8 as *const _, &1u8 as *const _));
+}
+
+// similar to above, but using &raw
+fn main_raw() {
+ let array = [0,1,2,3,4];
+ let array2 = [5,6,7,8,9];
+
+ // fat ptr comparison: addr then extra
+
+ // check ordering for arrays
+ let mut ptrs: Vec<*const [u8]> = vec![
+ &raw const array[0..0], &raw const array[0..1], &raw const array, &raw const array[1..]
+ ];
+
+ let array_addr = &raw const array as *const u8 as usize;
+ let array2_addr = &raw const array2 as *const u8 as usize;
+ if array2_addr < array_addr {
+ ptrs.insert(0, &raw const array2);
+ } else {
+ ptrs.push(&raw const array2);
+ }
+ assert_inorder(&ptrs, compare_au8);
+
+ let u8_ = (0u8, 1u8);
+ let u32_ = (4u32, 5u32);
+
+ // check ordering for ptrs
+ let buf: &mut [*const dyn Foo] = &mut [
+ &raw const u8_, &raw const u8_.0,
+ &raw const u32_, &raw const 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, compare_foo);
+
+ // 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(&[
+ &raw const ss.0 as *const S<[u8]>,
+ &raw const ss.1 as *const S<[u8]>,
+ &raw const ss.2 as *const S<[u8]>
+ ], compare_su8);
+}
+
+fn main() {
+ main_ref();
+ main_raw();
+}