File tree Expand file tree Collapse file tree 1 file changed +33
-0
lines changed Expand file tree Collapse file tree 1 file changed +33
-0
lines changed Original file line number Diff line number Diff line change 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+ }
You can’t perform that action at this time.
0 commit comments