Skip to content

Commit 201a306

Browse files
committed
Deprecate __int128, __uint128, __int128_t, and __uint128_t type in 1.0
1 parent f6b73a1 commit 201a306

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

Diff for: src/primitives.rs

+105
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,108 @@ pub type uint16_t = u16;
8787
pub type uint32_t = u32;
8888
#[deprecated(since = "0.2.55", note = "Use u64 instead.")]
8989
pub type uint64_t = u64;
90+
91+
cfg_if! {
92+
if #[cfg(all(
93+
target_arch = "aarch64",
94+
not(any(
95+
target_os = "windows",
96+
target_os = "macos",
97+
target_os = "ios",
98+
target_os = "tvos",
99+
target_os = "watchos"
100+
))
101+
))] {
102+
// This introduces partial support for FFI with __int128 and
103+
// equivalent types on platforms where Rust's definition is validated
104+
// to match the standard C ABI of that platform.
105+
//
106+
// Rust does not guarantee u128/i128 are sound for FFI, and its
107+
// definitions are in fact known to be incompatible. [0]
108+
//
109+
// However these problems aren't fundamental, and are just platform
110+
// inconsistencies. Specifically at the time of this writing:
111+
//
112+
// * For x64 SysV ABIs (everything but Windows), the types are underaligned.
113+
// * For all Windows ABIs, Microsoft doesn't actually officially define __int128,
114+
// and as a result different implementations don't actually agree on its ABI.
115+
//
116+
// But on the other major aarch64 platforms (android, linux, ios, macos) we have
117+
// validated that rustc has the right ABI for these types. This is important because
118+
// aarch64 uses these types in some fundamental OS types like user_fpsimd_struct,
119+
// which represents saved simd registers.
120+
//
121+
// Any API which uses these types will need to `#[ignore(improper_ctypes)]`
122+
// until the upstream rust issue is resolved, but this at least lets us make
123+
// progress on platforms where this type is important.
124+
//
125+
// The list of supported architectures and OSes is intentionally very restricted,
126+
// as careful work needs to be done to verify that a particular platform
127+
// has a conformant ABI.
128+
//
129+
// [0]: https://github.com/rust-lang/rust/issues/54341
130+
131+
/// C `__int128` (a GCC extension that's part of many ABIs)
132+
#[deprecated(since = "1.0", note = "Use i128 instead.")]
133+
pub type __int128 = i128;
134+
/// C `unsigned __int128` (a GCC extension that's part of many ABIs)
135+
#[deprecated(since = "1.0", note = "Use u128 instead.")]
136+
pub type __uint128 = u128;
137+
/// C __int128_t (alternate name for [__int128][])
138+
#[deprecated(since = "1.0", note = "Use i128 instead.")]
139+
pub type __int128_t = i128;
140+
/// C __uint128_t (alternate name for [__uint128][])
141+
#[deprecated(since = "1.0", note = "Use u128 instead.")]
142+
pub type __uint128_t = u128;
143+
144+
// NOTE: if you add more platforms to here, you may need to cfg
145+
// these consts. They should always match the platform's values
146+
// for `sizeof(__int128)` and `_Alignof(__int128)`.
147+
const _SIZE_128: usize = 16;
148+
const _ALIGN_128: usize = 16;
149+
150+
// FIXME(ctest): ctest doesn't handle `_` as an identifier so these tests are temporarily
151+
// disabled.
152+
// macro_rules! static_assert_eq {
153+
// ($a:expr, $b:expr) => {
154+
// const _: [(); $a] = [(); $b];
155+
// };
156+
// }
157+
//
158+
// // Since Rust doesn't officially guarantee that these types
159+
// // have compatible ABIs, we const assert that these values have the
160+
// // known size/align of the target platform's libc. If rustc ever
161+
// // tries to regress things, it will cause a compilation error.
162+
// //
163+
// // This isn't a bullet-proof solution because e.g. it doesn't
164+
// // catch the fact that llvm and gcc disagree on how x64 __int128
165+
// // is actually *passed* on the stack (clang underaligns it for
166+
// // the same reason that rustc *never* properly aligns it).
167+
// static_assert_eq!(core::mem::size_of::<__int128>(), _SIZE_128);
168+
// static_assert_eq!(core::mem::align_of::<__int128>(), _ALIGN_128);
169+
170+
// static_assert_eq!(core::mem::size_of::<__uint128>(), _SIZE_128);
171+
// static_assert_eq!(core::mem::align_of::<__uint128>(), _ALIGN_128);
172+
173+
// static_assert_eq!(core::mem::size_of::<__int128_t>(), _SIZE_128);
174+
// static_assert_eq!(core::mem::align_of::<__int128_t>(), _ALIGN_128);
175+
176+
// static_assert_eq!(core::mem::size_of::<__uint128_t>(), _SIZE_128);
177+
// static_assert_eq!(core::mem::align_of::<__uint128_t>(), _ALIGN_128);
178+
} else if #[cfg(all(
179+
target_arch = "aarch64",
180+
any(
181+
target_os = "macos",
182+
target_os = "ios",
183+
target_os = "tvos",
184+
target_os = "watchos"
185+
)
186+
))] {
187+
/// C `__int128_t`
188+
#[deprecated(since = "1.0", note = "Use i128 instead.")]
189+
pub type __int128_t = i128;
190+
/// C `__uint128_t`
191+
#[deprecated(since = "1.0", note = "Use ux128 instead.")]
192+
pub type __uint128_t = u128;
193+
}
194+
}

0 commit comments

Comments
 (0)