]> git.proxmox.com Git - rustc.git/blame - src/test/codegen/repr-transparent.rs
New upstream version 1.25.0+dfsg1
[rustc.git] / src / test / codegen / repr-transparent.rs
CommitLineData
2c00a5a8
XL
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
16use std::marker::PhantomData;
17
18pub struct Zst1;
19pub struct Zst2(());
20
21#[repr(transparent)]
22pub struct F32(f32);
23
24// CHECK: define float @test_F32(float %arg0)
25#[no_mangle]
26pub extern fn test_F32(_: F32) -> F32 { loop {} }
27
28#[repr(transparent)]
29pub struct Ptr(*mut u8);
30
31// CHECK: define i8* @test_Ptr(i8* %arg0)
32#[no_mangle]
33pub extern fn test_Ptr(_: Ptr) -> Ptr { loop {} }
34
35#[repr(transparent)]
36pub struct WithZst(u64, Zst1);
37
38// CHECK: define i64 @test_WithZst(i64 %arg0)
39#[no_mangle]
40pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} }
41
42#[repr(transparent)]
43pub 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]
48pub extern fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
49
50#[repr(transparent)]
51pub struct Generic<T>(T);
52
53// CHECK: define double @test_Generic(double %arg0)
54#[no_mangle]
55pub extern fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
56
57#[repr(transparent)]
58pub struct GenericPlusZst<T>(T, Zst2);
59
60#[repr(u8)]
61pub enum Bool { True, False, FileNotFound }
62
63// CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %arg0)
64#[no_mangle]
65pub extern fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
66
67#[repr(transparent)]
68pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
69
70// CHECK: define i16* @test_LifetimePhantom(i16* %arg0)
71#[no_mangle]
72pub 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)]
76pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> }
77
78pub struct Px;
79
80// CHECK: define float @test_UnitPhantom(float %arg0)
81#[no_mangle]
82pub extern fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
83
84#[repr(transparent)]
85pub struct TwoZsts(Zst1, i8, Zst2);
86
87// CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %arg0)
88#[no_mangle]
89pub extern fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
90
91#[repr(transparent)]
92pub struct Nested1(Zst2, Generic<f64>);
93
94// CHECK: define double @test_Nested1(double %arg0)
95#[no_mangle]
96pub extern fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
97
98#[repr(transparent)]
99pub struct Nested2(Nested1, Zst1);
100
101// CHECK: define double @test_Nested2(double %arg0)
102#[no_mangle]
103pub extern fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
104
105#[repr(simd)]
106struct f32x4(f32, f32, f32, f32);
107
108#[repr(transparent)]
109pub struct Vector(f32x4);
110
111// CHECK: define <4 x float> @test_Vector(<4 x float> %arg0)
112#[no_mangle]
113pub extern fn test_Vector(_: Vector) -> Vector { loop {} }
114
115trait Mirror { type It: ?Sized; }
116impl<T: ?Sized> Mirror for T { type It = Self; }
117
118#[repr(transparent)]
119pub struct StructWithProjection(<f32 as Mirror>::It);
120
121// CHECK: define float @test_Projection(float %arg0)
122#[no_mangle]
123pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
124
125
126// All that remains to be tested are aggregates. They are tested in separate files called repr-
127// transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR
128// function signatures vary so much that it's not reasonably possible to cover all of them with a
129// single CHECK line.
130//
131// You may be wondering why we don't just compare the return types and argument types for equality
132// with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes
133// containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of
134// pointee types yet, the IR function signature will be syntactically different (%Foo* vs
135// %FooWrapper*).