From aa38b7fcacbc5443a3bc6b205cd9ef50feabc932 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 8 Oct 2025 15:29:24 +0200 Subject: [PATCH 1/2] add `MaybeUninit` to `minicore` --- tests/auxiliary/minicore.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 24da2c4a1c4e..4830253e89d4 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -27,6 +27,7 @@ decl_macro, f16, f128, + transparent_unions, asm_experimental_arch, unboxed_closures )] @@ -127,6 +128,25 @@ pub struct ManuallyDrop { } impl Copy for ManuallyDrop {} +#[lang = "maybe_uninit"] +#[repr(transparent)] +pub union MaybeUninit { + uninit: (), + value: ManuallyDrop, +} + +impl Copy for MaybeUninit {} + +impl MaybeUninit { + pub const fn uninit() -> Self { + Self { uninit: () } + } + + pub const fn new(value: T) -> Self { + Self { value: ManuallyDrop { value } } + } +} + #[repr(transparent)] #[rustc_nonnull_optimization_guaranteed] pub struct NonNull { From 640c4b4f1e96fe37675493ccd8ab2e3c2229fd39 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 19 Apr 2026 18:30:12 +0200 Subject: [PATCH 2/2] cmse: test returning `MaybeUninit` The `MaybeUninit` type is `repr(transparent)`, so returning a `MaybeUninit` should work. The same is not true when using C or rust union types. --- .../cmse-nonsecure-call/return-via-stack.rs | 14 +++++++---- .../cmse-nonsecure-entry/params-via-stack.rs | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs index 55160f7a0f00..a8c69216e204 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs @@ -42,13 +42,13 @@ struct Test { i128: extern "cmse-nonsecure-call" fn() -> i128, //~ ERROR [E0798] } -#[repr(C)] -pub union ReprCUnionU64 { +#[repr(Rust)] +pub union ReprRustUnionU64 { _unused: u64, } -#[repr(Rust)] -pub union ReprRustUnionU64 { +#[repr(C)] +pub union ReprCUnionU64 { _unused: u64, } @@ -56,5 +56,11 @@ pub union ReprRustUnionU64 { pub fn test_union( f1: extern "cmse-nonsecure-call" fn() -> ReprRustUnionU64, //~ ERROR [E0798] f2: extern "cmse-nonsecure-call" fn() -> ReprCUnionU64, //~ ERROR [E0798] + + // MaybeUninit is a transparent union, and hence MaybeUninit is abi-compatible with u64, + // and thus allowed as a return type. + f3: extern "cmse-nonsecure-call" fn() -> MaybeUninit, + f4: extern "cmse-nonsecure-call" fn() -> MaybeUninit, + f5: extern "cmse-nonsecure-call" fn() -> MaybeUninit, ) { } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs index 2e73ef8c32f5..b46e73abad0e 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs @@ -45,3 +45,26 @@ pub extern "cmse-nonsecure-entry" fn four(_: Four) {} #[no_mangle] pub extern "cmse-nonsecure-entry" fn five(_: Five) {} //~ ERROR [E0798] + +#[repr(Rust)] +pub union ReprRustUnionU64 { + _unused: u64, +} + +#[repr(C)] +pub union ReprCUnionU64 { + _unused: u64, +} + +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "cmse-nonsecure-entry" fn union_rust(_: ReprRustUnionU64) {} + +#[no_mangle] +pub extern "cmse-nonsecure-entry" fn union_c(_: ReprCUnionU64) {} + +#[no_mangle] +pub extern "cmse-nonsecure-entry" fn maybe_uninit_32bit(_: MaybeUninit) {} + +#[no_mangle] +pub extern "cmse-nonsecure-entry" fn maybe_uninit_64bit(_: MaybeUninit) {}