about summary refs log tree commit diff
path: root/tests/ui/abi/bad-custom.rs
blob: 7c881134ccb4c0c5253123d41f07ef615b06a9d6 (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
120
121
//@ edition: 2021
//@ check-fail
//@ needs-asm-support
#![feature(abi_custom)]

#[unsafe(naked)]
extern "custom" fn must_be_unsafe(a: i64) -> i64 {
    //~^ ERROR functions with the "custom" ABI must be unsafe
    //~| ERROR invalid signature for `extern "custom"` function
    std::arch::naked_asm!("")
}

#[unsafe(naked)]
unsafe extern "custom" fn no_parameters(a: i64) {
    //~^ ERROR invalid signature for `extern "custom"` function
    std::arch::naked_asm!("")
}

#[unsafe(naked)]
unsafe extern "custom" fn no_return_type() -> i64 {
    //~^ ERROR invalid signature for `extern "custom"` function
    std::arch::naked_asm!("")
}

unsafe extern "custom" fn double(a: i64) -> i64 {
    //~^ ERROR items with the "custom" ABI can only be declared externally or defined via naked functions
    //~| ERROR invalid signature for `extern "custom"` function
    unimplemented!()
}

struct Thing(i64);

impl Thing {
    unsafe extern "custom" fn is_even(self) -> bool {
        //~^ ERROR items with the "custom" ABI can only be declared externally or defined via naked functions
        //~| ERROR invalid signature for `extern "custom"` function
        unimplemented!()
    }
}

trait BitwiseNot {
    unsafe extern "custom" fn bitwise_not(a: i64) -> i64 {
        //~^ ERROR items with the "custom" ABI can only be declared externally or defined via naked functions
        //~| ERROR invalid signature for `extern "custom"` function
        unimplemented!()
    }
}

impl BitwiseNot for Thing {}

trait Negate {
    extern "custom" fn negate(a: i64) -> i64;
    //~^ ERROR functions with the "custom" ABI must be unsafe
    //~| ERROR invalid signature for `extern "custom"` function
}

impl Negate for Thing {
    extern "custom" fn negate(a: i64) -> i64 {
        //~^ ERROR items with the "custom" ABI can only be declared externally or defined via naked functions
        //~| ERROR functions with the "custom" ABI must be unsafe
        //~| ERROR invalid signature for `extern "custom"` function
        -a
    }
}

unsafe extern "custom" {
    fn increment(a: i64) -> i64;
    //~^ ERROR invalid signature for `extern "custom"` function

    safe fn extern_cannot_be_safe();
    //~^ ERROR foreign functions with the "custom" ABI cannot be safe
}

fn caller(f: unsafe extern "custom" fn(i64) -> i64, mut x: i64) -> i64 {
    unsafe { f(x) }
    //~^ ERROR functions with the "custom" ABI cannot be called
}

fn caller_by_ref(f: &unsafe extern "custom" fn(i64) -> i64, mut x: i64) -> i64 {
    unsafe { f(x) }
    //~^ ERROR functions with the "custom" ABI cannot be called
}

type Custom = unsafe extern "custom" fn(i64) -> i64;

fn caller_alias(f: Custom, mut x: i64) -> i64 {
    unsafe { f(x) }
    //~^ ERROR functions with the "custom" ABI cannot be called
}

#[unsafe(naked)]
const unsafe extern "custom" fn no_const_fn() {
    std::arch::naked_asm!("")
    //~^ ERROR inline assembly is not allowed in constant functions
}

async unsafe extern "custom" fn no_async_fn() {
    //~^ ERROR items with the "custom" ABI can only be declared externally or defined via naked functions
    //~| ERROR functions with the "custom" ABI cannot be `async`
}

fn no_promotion_to_fn_trait(f: unsafe extern "custom" fn()) -> impl Fn()  {
    //~^ ERROR expected a `Fn()` closure, found `unsafe extern "custom" fn()`
    f
}

pub fn main() {
    unsafe {
        assert_eq!(double(21), 42);
        //~^ ERROR functions with the "custom" ABI cannot be called

        assert_eq!(unsafe { increment(41) }, 42);
        //~^ ERROR functions with the "custom" ABI cannot be called

        assert!(Thing(41).is_even());
        //~^ ERROR functions with the "custom" ABI cannot be called

        assert_eq!(Thing::bitwise_not(42), !42);
        //~^ ERROR functions with the "custom" ABI cannot be called
    }
}