Skip to content

Commit 797d593

Browse files
committed
run abi/compatibility test against a whole bunch of targets
1 parent e4a361a commit 797d593

File tree

1 file changed

+158
-10
lines changed

1 file changed

+158
-10
lines changed

tests/ui/abi/compatibility.rs

Lines changed: 158 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,159 @@
11
// check-pass
2+
// revisions: host
3+
// revisions: arm
4+
//[arm] compile-flags: --target arm-unknown-linux-gnueabi
5+
// revisions: aarch64
6+
//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
7+
// revisions: s390x
8+
//[s390x] compile-flags: --target s390x-unknown-linux-gnu
9+
// revisions: mips
10+
//[mips] compile-flags: --target mips-unknown-linux-gnu
11+
// revisions: mips64
12+
//[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
13+
// revisions: sparc
14+
//[sparc] compile-flags: --target sparc-unknown-linux-gnu
15+
// revisions: sparc64
16+
//[sparc64] compile-flags: --target sparc64-unknown-linux-gnu
17+
// revisions: powerpc64
18+
//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
19+
// revisions: riscv
20+
//[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu
21+
// revisions: loongarch64
22+
//[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
23+
// revisions: wasm
24+
//[wasm] compile-flags: --target wasm32-unknown-unknown
25+
// revisions: nvptx64
26+
//[nvptx64] compile-flags: --target nvptx64-nvidia-cuda
227
#![feature(rustc_attrs, unsized_fn_params, transparent_unions)]
28+
#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)]
329
#![allow(unused, improper_ctypes_definitions, internal_features)]
4-
use std::marker::PhantomData;
5-
use std::mem::ManuallyDrop;
6-
use std::num::NonZeroI32;
7-
use std::ptr::NonNull;
830

9-
// FIXME: a bunch of targets are broken in various ways.
31+
// FIXME: some targets are broken in various ways.
1032
// Hence there are `cfg` throughout this test to disable parts of it on those targets.
1133
// sparc64: https://github.com/rust-lang/rust/issues/115336
1234
// mips64: https://github.com/rust-lang/rust/issues/115404
1335

36+
#[cfg(host)]
37+
use std::{
38+
any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZeroI32, ptr::NonNull, rc::Rc,
39+
sync::Arc,
40+
};
41+
42+
/// To work cross-target this test must be no_core.
43+
/// This little prelude supplies what we need.
44+
#[cfg(not(host))]
45+
mod prelude {
46+
#[lang = "sized"]
47+
pub trait Sized {}
48+
49+
#[lang = "receiver"]
50+
pub trait Receiver {}
51+
impl<T: ?Sized> Receiver for &T {}
52+
impl<T: ?Sized> Receiver for &mut T {}
53+
54+
#[lang = "copy"]
55+
pub trait Copy: Sized {}
56+
impl Copy for i32 {}
57+
impl Copy for f32 {}
58+
impl<T: ?Sized> Copy for &T {}
59+
impl<T: ?Sized> Copy for *const T {}
60+
impl<T: ?Sized> Copy for *mut T {}
61+
62+
#[lang = "clone"]
63+
pub trait Clone: Sized {
64+
fn clone(&self) -> Self;
65+
}
66+
67+
#[lang = "phantom_data"]
68+
pub struct PhantomData<T: ?Sized>;
69+
impl<T: ?Sized> Copy for PhantomData<T> {}
70+
71+
#[lang = "unsafe_cell"]
72+
#[repr(transparent)]
73+
pub struct UnsafeCell<T: ?Sized> {
74+
value: T,
75+
}
76+
77+
pub trait Any: 'static {}
78+
79+
pub enum Option<T> {
80+
None,
81+
Some(T),
82+
}
83+
impl<T: Copy> Copy for Option<T> {}
84+
85+
pub enum Result<T, E> {
86+
Ok(T),
87+
Err(E),
88+
}
89+
impl<T: Copy, E: Copy> Copy for Result<T, E> {}
90+
91+
#[lang = "manually_drop"]
92+
#[repr(transparent)]
93+
pub struct ManuallyDrop<T: ?Sized> {
94+
value: T,
95+
}
96+
impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {}
97+
98+
#[repr(transparent)]
99+
#[rustc_layout_scalar_valid_range_start(1)]
100+
#[rustc_nonnull_optimization_guaranteed]
101+
pub struct NonNull<T: ?Sized> {
102+
pointer: *const T,
103+
}
104+
impl<T: ?Sized> Copy for NonNull<T> {}
105+
106+
#[repr(transparent)]
107+
#[rustc_layout_scalar_valid_range_start(1)]
108+
#[rustc_nonnull_optimization_guaranteed]
109+
pub struct NonZeroI32(i32);
110+
111+
// This just stands in for a non-trivial type.
112+
pub struct Vec<T> {
113+
ptr: NonNull<T>,
114+
cap: usize,
115+
len: usize,
116+
}
117+
118+
pub struct Unique<T: ?Sized> {
119+
pub pointer: NonNull<T>,
120+
pub _marker: PhantomData<T>,
121+
}
122+
123+
pub struct Global;
124+
125+
#[lang = "owned_box"]
126+
pub struct Box<T: ?Sized, A = Global>(Unique<T>, A);
127+
128+
#[repr(C)]
129+
struct RcBox<T: ?Sized> {
130+
strong: UnsafeCell<usize>,
131+
weak: UnsafeCell<usize>,
132+
value: T,
133+
}
134+
pub struct Rc<T: ?Sized, A = Global> {
135+
ptr: NonNull<RcBox<T>>,
136+
phantom: PhantomData<RcBox<T>>,
137+
alloc: A,
138+
}
139+
140+
#[repr(C, align(8))]
141+
struct AtomicUsize(usize);
142+
#[repr(C)]
143+
struct ArcInner<T: ?Sized> {
144+
strong: AtomicUsize,
145+
weak: AtomicUsize,
146+
data: T,
147+
}
148+
pub struct Arc<T: ?Sized, A = Global> {
149+
ptr: NonNull<ArcInner<T>>,
150+
phantom: PhantomData<ArcInner<T>>,
151+
alloc: A,
152+
}
153+
}
154+
#[cfg(not(host))]
155+
use prelude::*;
156+
14157
macro_rules! assert_abi_compatible {
15158
($name:ident, $t1:ty, $t2:ty) => {
16159
mod $name {
@@ -26,8 +169,13 @@ macro_rules! assert_abi_compatible {
26169
};
27170
}
28171

29-
#[derive(Copy, Clone)]
30172
struct Zst;
173+
impl Copy for Zst {}
174+
impl Clone for Zst {
175+
fn clone(&self) -> Self {
176+
Zst
177+
}
178+
}
31179

32180
#[repr(C)]
33181
struct ReprC1<T: ?Sized>(T);
@@ -85,8 +233,8 @@ test_abi_compatible!(nonzero_int, NonZeroI32, i32);
85233

86234
// `DispatchFromDyn` relies on ABI compatibility.
87235
// This is interesting since these types are not `repr(transparent)`.
88-
test_abi_compatible!(rc, std::rc::Rc<i32>, *mut i32);
89-
test_abi_compatible!(arc, std::sync::Arc<i32>, *mut i32);
236+
test_abi_compatible!(rc, Rc<i32>, *mut i32);
237+
test_abi_compatible!(arc, Arc<i32>, *mut i32);
90238

91239
// `repr(transparent)` compatibility.
92240
#[repr(transparent)]
@@ -160,7 +308,7 @@ mod unsized_ {
160308
use super::*;
161309
test_transparent_unsized!(str_, str);
162310
test_transparent_unsized!(slice, [u8]);
163-
test_transparent_unsized!(dyn_trait, dyn std::any::Any);
311+
test_transparent_unsized!(dyn_trait, dyn Any);
164312
}
165313

166314
// RFC 3391 <https://rust-lang.github.io/rfcs/3391-result_ffi_guarantees.html>.
@@ -185,7 +333,7 @@ test_nonnull!(ref_unsized, &[i32]);
185333
test_nonnull!(mut_unsized, &mut [i32]);
186334
test_nonnull!(fn_, fn());
187335
test_nonnull!(nonnull, NonNull<i32>);
188-
test_nonnull!(nonnull_unsized, NonNull<dyn std::fmt::Debug>);
336+
test_nonnull!(nonnull_unsized, NonNull<dyn Any>);
189337
test_nonnull!(non_zero, NonZeroI32);
190338

191339
fn main() {}

0 commit comments

Comments
 (0)