Skip to content

Commit 11153ef

Browse files
committed
Add test that uninhabited repr(transparent) type has same function return ABI as wrapped type.
1 parent 3f718d8 commit 11153ef

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//@ run-pass
2+
//@ needs-unwind
3+
// See https://github.com/rust-lang/rust/issues/135802
4+
5+
enum Void {}
6+
7+
// Should be ABI-compatible with T, but wasn't prior to the PR adding this test.
8+
#[repr(transparent)]
9+
struct NoReturn<T>(T, Void);
10+
11+
// Returned by invisible reference (in most ABIs)
12+
#[allow(dead_code)]
13+
struct Large(u64, u64, u64);
14+
15+
// Prior to the PR adding this test, this function had a different ABI than
16+
// `fn() -> Large` (on `x86_64-unknown-linux-gnu` at least), so calling it as `fn() -> Large`
17+
// would pass the return place pointer in rdi and `correct` in rsi, but the function
18+
// would expect `correct` in rdi.
19+
fn never(correct: &mut bool) -> NoReturn<Large> {
20+
*correct = true;
21+
panic!("catch this")
22+
}
23+
24+
fn main() {
25+
let mut correct = false;
26+
let never: fn(&mut bool) -> NoReturn<Large> = never;
27+
// Safety: `NoReturn<Large>` is a `repr(transparent)` wrapper around `Large`,
28+
// so they should be ABI-compatible.
29+
let never: fn(&mut bool) -> Large = unsafe { std::mem::transmute(never) };
30+
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| never(&mut correct)));
31+
assert!(result.is_err(), "function should have panicked");
32+
assert!(correct, "function should have stored `true` into `correct`");
33+
}

0 commit comments

Comments
 (0)