about summary refs log tree commit diff
path: root/tests/ui/c-variadic/inherent-method.rs
blob: c5256aaa1fea393466630cf4abbb3281b9602445 (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
//@ run-pass
//@ ignore-backends: gcc
#![feature(c_variadic)]

#[repr(transparent)]
struct S(i32);

impl S {
    unsafe extern "C" fn associated_function(mut ap: ...) -> i32 {
        unsafe { ap.arg() }
    }

    unsafe extern "C" fn method_owned(self, mut ap: ...) -> i32 {
        self.0 + unsafe { ap.arg::<i32>() }
    }

    unsafe extern "C" fn method_ref(&self, mut ap: ...) -> i32 {
        self.0 + unsafe { ap.arg::<i32>() }
    }

    unsafe extern "C" fn method_mut(&mut self, mut ap: ...) -> i32 {
        self.0 + unsafe { ap.arg::<i32>() }
    }

    unsafe extern "C" fn fat_pointer(self: Box<Self>, mut ap: ...) -> i32 {
        self.0 + unsafe { ap.arg::<i32>() }
    }
}

fn main() {
    unsafe {
        assert_eq!(S::associated_function(32), 32);
        assert_eq!(S(100).method_owned(32), 132);
        assert_eq!(S(100).method_ref(32), 132);
        assert_eq!(S(100).method_mut(32), 132);
        assert_eq!(S::fat_pointer(Box::new(S(100)), 32), 132);

        type Method<T> = unsafe extern "C" fn(T, ...) -> i32;

        assert_eq!((S::associated_function as unsafe extern "C" fn(...) -> i32)(32), 32);
        assert_eq!((S::method_owned as Method<_>)(S(100), 32), 132);
        assert_eq!((S::method_ref as Method<_>)(&S(100), 32), 132);
        assert_eq!((S::method_mut as Method<_>)(&mut S(100), 32), 132);
        assert_eq!((S::fat_pointer as Method<_>)(Box::new(S(100)), 32), 132);
    }
}