blob: 7c881134ccb4c0c5253123d41f07ef615b06a9d6 [file] [log] [blame]
//@ 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
}
}