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]