From 03c43f56f0adb94200e42b1998b582f9b972bac7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 12 Dec 2020 21:07:17 -0800 Subject: [PATCH] Document and static assert assumptions on size_t size --- src/cxx.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/cxx.cc b/src/cxx.cc index c17e0fb62..a11ba12a6 100644 --- a/src/cxx.cc +++ b/src/cxx.cc @@ -249,6 +249,23 @@ std::ostream &operator<<(std::ostream &os, const Str &s) { return os; } +// Rust specifies that usize is ABI compatible with C's uintptr_t. +// https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize +// However there is no direct Rust equivalent for size_t. C does not guarantee +// that size_t and uintptr_t are compatible. In practice though, on all +// platforms supported by Rust, they are identical for ABI purposes. See the +// libc crate which unconditionally defines libc::size_t = usize. We expect the +// same here and these assertions are just here to explicitly document that. +// *Note that no assumption is made about C++ name mangling of signatures +// containing these types, not here nor anywhere in CXX.* +static_assert(sizeof(size_t) == sizeof(uintptr_t), "unsupported size_t size"); +static_assert(alignof(size_t) == alignof(uintptr_t), + "unsupported size_t alignment"); +static_assert(sizeof(rust::isize) == sizeof(intptr_t), + "unsupported ssize_t size"); +static_assert(alignof(rust::isize) == alignof(intptr_t), + "unsupported ssize_t alignment"); + static_assert(std::is_trivially_copy_constructible::value, "trivial Str(const Str &)"); static_assert(std::is_trivially_copy_assignable::value,