Generate `static_assert(std::is_trivially_copy..._v<...>)` for `Copy` types.
PiperOrigin-RevId: 538194228
diff --git a/cc_bindings_from_rs/bindings.rs b/cc_bindings_from_rs/bindings.rs
index 483626c..0c4d07b 100644
--- a/cc_bindings_from_rs/bindings.rs
+++ b/cc_bindings_from_rs/bindings.rs
@@ -1561,7 +1561,15 @@
#cc_struct_name(const #cc_struct_name&) = default; __NEWLINE__
#cc_struct_name& operator=(const #cc_struct_name&) = default;
});
- return Ok(ApiSnippets { main_api, ..Default::default() });
+ let cc_details = CcSnippet::with_include(
+ quote! {
+ static_assert(std::is_trivially_copy_constructible_v<#cc_struct_name>);
+ static_assert(std::is_trivially_copy_assignable_v<#cc_struct_name>);
+ },
+ CcInclude::type_traits(),
+ );
+
+ return Ok(ApiSnippets { main_api, cc_details, rs_details: quote! {} });
}
// TODO(b/259741191): Implement bindings for `Clone::clone` and
@@ -4211,12 +4219,21 @@
}
);
- // Trivial copy doesn't require any C++/Rust details.
+ // Trivial copy doesn't require any C++ details except `static_assert`s.
assert_cc_not_matches!(result.cc_details.tokens, quote! { Point::Point(const Point&) },);
assert_cc_not_matches!(
result.cc_details.tokens,
quote! { Point::operator=(const Point&) },
);
+ assert_cc_matches!(
+ result.cc_details.tokens,
+ quote! {
+ static_assert(std::is_trivially_copy_constructible_v<Point>);
+ static_assert(std::is_trivially_copy_assignable_v<Point>);
+ },
+ );
+
+ // Trivial copy doesn't require any Rust details.
assert_rs_not_matches!(result.rs_details, quote! { Copy });
assert_rs_not_matches!(result.rs_details, quote! { copy });
});
diff --git a/common/code_gen_utils.rs b/common/code_gen_utils.rs
index f3439a0..0daef88 100644
--- a/common/code_gen_utils.rs
+++ b/common/code_gen_utils.rs
@@ -219,32 +219,39 @@
impl CcInclude {
/// Creates a `CcInclude` that represents `#include <cstddef>` and provides
- /// C++ types like `std::size_t` or `std::ptrdiff_t`. See also
+ /// C++ types like `std::size_t` or `std::ptrdiff_t`. See
/// https://en.cppreference.com/w/cpp/header/cstddef
pub fn cstddef() -> Self {
Self::SystemHeader("cstddef")
}
/// Creates a `CcInclude` that represents `#include <cstdint>` and provides
- /// C++ types like `std::int16_t` or `std::uint32_t`. See also
+ /// C++ types like `std::int16_t` or `std::uint32_t`. See
/// https://en.cppreference.com/w/cpp/header/cstdint
pub fn cstdint() -> Self {
Self::SystemHeader("cstdint")
}
/// Creates a `CcInclude` that represents `#include <memory>`.
- /// See also https://en.cppreference.com/w/cpp/header/memory
+ /// See https://en.cppreference.com/w/cpp/header/memory
pub fn memory() -> Self {
Self::SystemHeader("memory")
}
/// Creates a `CcInclude` that represents `#include <utility>` and provides
/// C++ functions like `std::move` and C++ types like `std::tuple`.
- /// See also https://en.cppreference.com/w/cpp/header/utility
+ /// See https://en.cppreference.com/w/cpp/header/utility
pub fn utility() -> Self {
Self::SystemHeader("utility")
}
+ /// Creates a `CcInclude` that represents `#include <type_traits>` and
+ /// provides C++ APIs like `std::is_trivially_copy_constructible_v`.
+ /// See https://en.cppreference.com/w/cpp/header/type_traits
+ pub fn type_traits() -> Self {
+ Self::SystemHeader("type_traits")
+ }
+
/// Creates a user include: `#include "some/path/to/header.h"`.
pub fn user_header(path: Rc<str>) -> Self {
Self::UserHeader(path)
@@ -398,10 +405,7 @@
#[test]
fn test_format_cc_ident_basic() {
- assert_cc_matches!(
- format_cc_ident("foo").unwrap(),
- quote! { foo }
- );
+ assert_cc_matches!(format_cc_ident("foo").unwrap(), quote! { foo });
}
#[test]
@@ -416,10 +420,7 @@
#[test]
fn test_format_cc_ident_reserved_rust_keyword() {
- assert_cc_matches!(
- format_cc_ident("impl").unwrap(),
- quote! { impl }
- );
+ assert_cc_matches!(format_cc_ident("impl").unwrap(), quote! { impl });
}
#[test]
@@ -443,21 +444,12 @@
// https://en.cppreference.com/w/cpp/language/identifiers#Unqualified_identifiers
// These may appear in `IR::Func::name`.
- assert_cc_matches!(
- format_cc_ident("operator==").unwrap(),
- quote! { operator== }
- );
- assert_cc_matches!(
- format_cc_ident("operator new").unwrap(),
- quote! { operator new }
- );
+ assert_cc_matches!(format_cc_ident("operator==").unwrap(), quote! { operator== });
+ assert_cc_matches!(format_cc_ident("operator new").unwrap(), quote! { operator new });
// This may appear in `IR::Record::cc_name` (although in practice these will
// be namespace-qualified most of the time).
- assert_cc_matches!(
- format_cc_ident("MyTemplate<int>").unwrap(),
- quote! { MyTemplate<int> }
- );
+ assert_cc_matches!(format_cc_ident("MyTemplate<int>").unwrap(), quote! { MyTemplate<int> });
}
#[test]