File tree 1 file changed +33
-0
lines changed
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