]> git.lizzy.rs Git - rust.git/blob - src/test/codegen/repr-transparent.rs
Auto merge of #61212 - alexcrichton:skip-rustc, r=pietroalbini
[rust.git] / src / test / codegen / repr-transparent.rs
1 // compile-flags: -C no-prepopulate-passes
2
3 #![crate_type="lib"]
4 #![feature(repr_simd)]
5
6 use std::marker::PhantomData;
7
8 pub struct Zst1;
9 pub struct Zst2(());
10
11 #[repr(transparent)]
12 pub struct F32(f32);
13
14 // CHECK: define float @test_F32(float %arg0)
15 #[no_mangle]
16 pub extern fn test_F32(_: F32) -> F32 { loop {} }
17
18 #[repr(transparent)]
19 pub struct Ptr(*mut u8);
20
21 // CHECK: define i8* @test_Ptr(i8* %arg0)
22 #[no_mangle]
23 pub extern fn test_Ptr(_: Ptr) -> Ptr { loop {} }
24
25 #[repr(transparent)]
26 pub struct WithZst(u64, Zst1);
27
28 // CHECK: define i64 @test_WithZst(i64 %arg0)
29 #[no_mangle]
30 pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} }
31
32 #[repr(transparent)]
33 pub struct WithZeroSizedArray(*const f32, [i8; 0]);
34
35 // Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
36 // CHECK: define i32* @test_WithZeroSizedArray(i32* %arg0)
37 #[no_mangle]
38 pub extern fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
39
40 #[repr(transparent)]
41 pub struct Generic<T>(T);
42
43 // CHECK: define double @test_Generic(double %arg0)
44 #[no_mangle]
45 pub extern fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
46
47 #[repr(transparent)]
48 pub struct GenericPlusZst<T>(T, Zst2);
49
50 #[repr(u8)]
51 pub enum Bool { True, False, FileNotFound }
52
53 // CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %arg0)
54 #[no_mangle]
55 pub extern fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
56
57 #[repr(transparent)]
58 pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
59
60 // CHECK: define i16* @test_LifetimePhantom(i16* %arg0)
61 #[no_mangle]
62 pub extern fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
63
64 // This works despite current alignment resrictions because PhantomData is always align(1)
65 #[repr(transparent)]
66 pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> }
67
68 pub struct Px;
69
70 // CHECK: define float @test_UnitPhantom(float %arg0)
71 #[no_mangle]
72 pub extern fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
73
74 #[repr(transparent)]
75 pub struct TwoZsts(Zst1, i8, Zst2);
76
77 // CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %arg0)
78 #[no_mangle]
79 pub extern fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
80
81 #[repr(transparent)]
82 pub struct Nested1(Zst2, Generic<f64>);
83
84 // CHECK: define double @test_Nested1(double %arg0)
85 #[no_mangle]
86 pub extern fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
87
88 #[repr(transparent)]
89 pub struct Nested2(Nested1, Zst1);
90
91 // CHECK: define double @test_Nested2(double %arg0)
92 #[no_mangle]
93 pub extern fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
94
95 #[repr(simd)]
96 struct f32x4(f32, f32, f32, f32);
97
98 #[repr(transparent)]
99 pub struct Vector(f32x4);
100
101 // CHECK: define <4 x float> @test_Vector(<4 x float> %arg0)
102 #[no_mangle]
103 pub extern fn test_Vector(_: Vector) -> Vector { loop {} }
104
105 trait Mirror { type It: ?Sized; }
106 impl<T: ?Sized> Mirror for T { type It = Self; }
107
108 #[repr(transparent)]
109 pub struct StructWithProjection(<f32 as Mirror>::It);
110
111 // CHECK: define float @test_Projection(float %arg0)
112 #[no_mangle]
113 pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
114
115
116 // All that remains to be tested are aggregates. They are tested in separate files called repr-
117 // transparent-*.rs  with `only-*` or `ignore-*` directives, because the expected LLVM IR
118 // function signatures vary so much that it's not reasonably possible to cover all of them with a
119 // single CHECK line.
120 //
121 // You may be wondering why we don't just compare the return types and argument types for equality
122 // with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes
123 // containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of
124 // pointee types yet, the IR function signature will be syntactically different (%Foo* vs
125 // %FooWrapper*).