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