]> git.lizzy.rs Git - rust.git/blob - src/test/codegen/repr-transparent.rs
Optimized error reporting for recursive requirements #47720
[rust.git] / src / test / codegen / repr-transparent.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // compile-flags: -C no-prepopulate-passes
12
13 #![crate_type="lib"]
14 #![feature(repr_transparent, repr_simd)]
15
16 use std::marker::PhantomData;
17
18 pub struct Zst1;
19 pub struct Zst2(());
20
21 #[repr(transparent)]
22 pub struct F32(f32);
23
24 // CHECK: define float @test_F32(float %arg0)
25 #[no_mangle]
26 pub extern fn test_F32(_: F32) -> F32 { loop {} }
27
28 #[repr(transparent)]
29 pub struct Ptr(*mut u8);
30
31 // CHECK: define i8* @test_Ptr(i8* %arg0)
32 #[no_mangle]
33 pub extern fn test_Ptr(_: Ptr) -> Ptr { loop {} }
34
35 #[repr(transparent)]
36 pub struct WithZst(u64, Zst1);
37
38 // CHECK: define i64 @test_WithZst(i64 %arg0)
39 #[no_mangle]
40 pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} }
41
42 #[repr(transparent)]
43 pub struct WithZeroSizedArray(*const f32, [i8; 0]);
44
45 // Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
46 // CHECK: define i32* @test_WithZeroSizedArray(i32* %arg0)
47 #[no_mangle]
48 pub extern fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
49
50 #[repr(transparent)]
51 pub struct Generic<T>(T);
52
53 // CHECK: define double @test_Generic(double %arg0)
54 #[no_mangle]
55 pub extern fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
56
57 #[repr(transparent)]
58 pub struct GenericPlusZst<T>(T, Zst2);
59
60 #[repr(u8)]
61 pub enum Bool { True, False, FileNotFound }
62
63 // CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %arg0)
64 #[no_mangle]
65 pub extern fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
66
67 #[repr(transparent)]
68 pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
69
70 // CHECK: define i16* @test_LifetimePhantom(i16* %arg0)
71 #[no_mangle]
72 pub extern fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
73
74 // This works despite current alignment resrictions because PhantomData is always align(1)
75 #[repr(transparent)]
76 pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> }
77
78 pub struct Px;
79
80 // CHECK: define float @test_UnitPhantom(float %arg0)
81 #[no_mangle]
82 pub extern fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
83
84 #[repr(transparent)]
85 pub struct TwoZsts(Zst1, i8, Zst2);
86
87 // CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %arg0)
88 #[no_mangle]
89 pub extern fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
90
91 #[repr(transparent)]
92 pub struct Nested1(Zst2, Generic<f64>);
93
94 // CHECK: define double @test_Nested1(double %arg0)
95 #[no_mangle]
96 pub extern fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
97
98 #[repr(transparent)]
99 pub struct Nested2(Nested1, Zst1);
100
101 // CHECK: define double @test_Nested2(double %arg0)
102 #[no_mangle]
103 pub extern fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
104
105 #[repr(simd)]
106 struct f32x4(f32, f32, f32, f32);
107
108 #[repr(transparent)]
109 pub struct Vector(f32x4);
110
111 // CHECK: define <4 x float> @test_Vector(<4 x float> %arg0)
112 #[no_mangle]
113 pub extern fn test_Vector(_: Vector) -> Vector { loop {} }
114
115 trait Mirror { type It: ?Sized; }
116 impl<T: ?Sized> Mirror for T { type It = Self; }
117
118 #[repr(transparent)]
119 pub struct StructWithProjection(<f32 as Mirror>::It);
120
121 // CHECK: define float @test_Projection(float %arg0)
122 #[no_mangle]
123 pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
124
125
126 // The rest of this file tests newtypes around small aggregates on an ABI where small aggregates are
127 // packed into one register. This is ABI-dependent, so instead we focus on one ABI and supply a
128 // dummy definition for other ABIs to keep FileCheck happy.
129 //
130 // Bigger aggregates are tested in separate files called repr-transparent-aggregate-*.rs because
131 // there, the expected LLVM IR function signatures vary so much that it's not reasonably possible to
132 // cover all of them with a single CHECK line. Instead we group ABIs by the general "shape" of the
133 // signature and have a separate test file for each bin.
134 //
135 // PS: You may be wondering why we don't just compare the return types and argument types for
136 // equality with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on
137 // newtypes containing aggregates. This is OK on all ABIs we support, but because LLVM has not
138 // gotten rid of pointee types yet, the IR function signature will be syntactically different (%Foo*
139 // vs %FooWrapper*).
140
141 #[repr(C)]
142 pub struct Rgb8 { r: u8, g: u8, b: u8 }
143
144 #[repr(transparent)]
145 pub struct Rgb8Wrap(Rgb8);
146
147 // NB: closing parenthesis is missing because sometimes the argument has a name and sometimes not
148 // CHECK: define i32 @test_Rgb8Wrap(i32
149 #[no_mangle]
150 #[cfg(all(target_arch="x86_64", target_os="linux"))]
151 pub extern fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap { loop {} }
152
153 #[cfg(not(all(target_arch="x86_64", target_os="linux")))]
154 #[no_mangle]
155 pub extern fn test_Rgb8Wrap(_: u32) -> u32 { loop {} }
156
157 // Same as with the small struct above: ABI-dependent, we only test the interesting case
158 // (ABIs that pack the aggregate into a scalar) and stub it out on other ABIs
159
160 #[repr(C)]
161 pub union FloatBits {
162     float: f32,
163     bits: u32,
164 }
165
166 #[repr(transparent)]
167 pub struct SmallUnion(FloatBits);
168
169 // NB: closing parenthesis is missing because sometimes the argument has a name and sometimes not
170 // CHECK: define i32 @test_SmallUnion(i32
171 #[no_mangle]
172 #[cfg(all(target_arch="x86_64", target_os="linux"))]
173 pub extern fn test_SmallUnion(_: SmallUnion) -> SmallUnion { loop {} }
174
175 #[cfg(not(all(target_arch="x86_64", target_os="linux")))]
176 #[no_mangle]
177 pub extern fn test_SmallUnion(_: u32) -> u32 { loop {} }