diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index a51517338e55..5411e8f8176b 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -703,13 +703,6 @@ impl<'a, Ty> FnAbi<'a, Ty> { "bpf" => bpf::compute_abi_info(cx, self), arch => panic!("no lowering implemented for {arch}"), } - // Double check that any argument types annotated with the - // `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute are passed indirectly. - for arg in &self.args { - if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { - assert!(matches!(arg.mode, PassMode::Indirect { on_stack: false, .. })); - } - } } pub fn adjust_for_rust_abi(&mut self, cx: &C) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 0f09e548f0e2..f98f161e8093 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,3 +1,4 @@ +use std::assert_matches::assert_matches; use std::iter; use rustc_abi::Primitive::Pointer; @@ -388,6 +389,12 @@ fn fn_abi_sanity_check<'tcx>( if let PassMode::Indirect { on_stack, .. } = arg.mode { assert!(!on_stack, "rust abi shouldn't use on_stack"); } + } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + assert_matches!( + arg.mode, + PassMode::Indirect { on_stack: false, .. }, + "the {spec_abi} ABI does not implement `#[rustc_pass_indirectly_in_non_rustic_abis]`" + ); } match &arg.mode { diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 46ccf330d1c2..3c9587d383e3 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -299,3 +299,15 @@ impl<'f> Drop for VaListImpl<'f> { // This works for now, since `va_end` is a no-op on all current LLVM targets. } } + +// Checks (via an assert in `compiler/rustc_ty_utils/src/abi.rs`) that the C ABI for the current +// target correctly implements `rustc_pass_indirectly_in_non_rustic_abis`. +const _: () = { + #[repr(C)] + #[rustc_pass_indirectly_in_non_rustic_abis] + struct Type(usize); + + const extern "C" fn c(_: Type) {} + + c(Type(0)) +};