Don't generate thunks for overloaded functions.
This is slightly hacky, but lets me move past some truly nasty overload sets in Abseil when testing this out.
PiperOrigin-RevId: 478958577
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 3534b7d..91f25f6 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -2331,9 +2331,9 @@
}
Item::Namespace(namespace) => generate_namespace(db, namespace)?,
Item::UseMod(use_mod) => {
- let UseMod {path, mod_name, ..} = &**use_mod;
+ let UseMod { path, mod_name, .. } = &**use_mod;
let mod_name = make_rs_ident(&mod_name.identifier);
- GeneratedItem {
+ GeneratedItem {
item: quote! {
#[path = #path]
mod #mod_name;
@@ -3307,9 +3307,20 @@
if can_skip_cc_thunk(db, func) {
continue;
}
- if db.generate_func(func.clone()).unwrap_or_default().is_none() {
- // No function was generated that will call this thunk.
- continue;
+ match db.generate_func(func.clone()).unwrap_or_default() {
+ None => {
+ // No function was generated that will call this thunk.
+ continue;
+ }
+ Some(generated) => {
+ let (_, _, function_id) = &*generated;
+ // TODO(jeanpierreda): this should be moved into can_skip_cc_thunk, but that'd be
+ // cyclic right now, because overloaded_funcs calls generate_func calls
+ // can_skip_cc_thunk. We probably need to break generate_func apart.
+ if db.overloaded_funcs().contains(function_id) {
+ continue;
+ }
+ }
}
let thunk_ident = thunk_ident(func);
@@ -6348,11 +6359,11 @@
// single parameter.
let ir = ir_from_cc(
r#" #pragma clang lifetime_elision
- void f();
- void f(int i);
+ void f() {}
+ void f(int i) {}
struct S1 final {
- void f();
- void f(int i);
+ void f() {}
+ void f(int i) {}
};
struct S2 final {
void f();
@@ -6366,7 +6377,7 @@
namespace bar { void not_overloaded(); }
"#,
)?;
- let rs_api = generate_bindings_tokens(ir)?.rs_api;
+ let BindingsTokens { rs_api, rs_api_impl } = generate_bindings_tokens(ir)?;
let rs_api_str = tokens_to_string(rs_api.clone())?;
// Cannot overload free functions.
@@ -6378,6 +6389,9 @@
assert!(rs_api_str.contains("Error while generating bindings for item 'S1::f'"));
assert_rs_not_matches!(rs_api, quote! {pub fn f(... S1 ...)});
+ // And thunks aren't generated for either.
+ assert_cc_not_matches!(rs_api_impl, quote! {f});
+
// But we can import member functions that have the same name as a free
// function.
assert_rs_matches!(rs_api, quote! {pub fn f<'a>(&'a mut self)});
diff --git a/rs_bindings_from_cc/test/golden/overloads.h b/rs_bindings_from_cc/test/golden/overloads.h
new file mode 100644
index 0000000..fbdc039
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/overloads.h
@@ -0,0 +1,29 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_OVERLOADS_H_
+#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_OVERLOADS_H_
+
+#include <type_traits>
+
+void Overload();
+void Overload(int);
+
+// An overload where at least one of the functions is uncallable.
+// This can happen in real code, one example is the `void*` overload of
+// absl::flags_internal::FlagImpl::Read().
+inline void UncallableOverload(void* x) {}
+
+// TODO(b/251045039): delete this overload
+inline void UncallableOverload(int* x) {}
+
+// This template is attempting sfinae, but is ill-formed. :(
+template <typename T, std::enable_if_t<sizeof(T) == 1> = 0>
+void UncallableOverload(T* x) {}
+
+inline void AlsoTemplateOverload() {}
+template <typename T>
+void AlsoTemplateOverload(T x) {}
+
+#endif // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_OVERLOADS_H_
diff --git a/rs_bindings_from_cc/test/golden/overloads_rs_api.rs b/rs_bindings_from_cc/test/golden/overloads_rs_api.rs
new file mode 100644
index 0000000..2de0cf6
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/overloads_rs_api.rs
@@ -0,0 +1,232 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// Automatically @generated Rust bindings for C++ target
+// //rs_bindings_from_cc/test/golden:overloads_cc
+#![rustfmt::skip]
+#![feature(custom_inner_attributes, negative_impls)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![deny(warnings)]
+
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// rs_bindings_from_cc/test/golden/overloads.h;l=10
+// Error while generating bindings for item 'Overload':
+// Cannot generate bindings for overloaded function
+
+// rs_bindings_from_cc/test/golden/overloads.h;l=11
+// Error while generating bindings for item 'Overload':
+// Cannot generate bindings for overloaded function
+
+// rs_bindings_from_cc/test/golden/overloads.h;l=16
+// Error while generating bindings for item 'UncallableOverload':
+// Cannot generate bindings for overloaded function
+
+// rs_bindings_from_cc/test/golden/overloads.h;l=19
+// Error while generating bindings for item 'UncallableOverload':
+// Cannot generate bindings for overloaded function
+
+// rs_bindings_from_cc/test/golden/overloads.h;l=22
+// Error while generating bindings for item 'UncallableOverload':
+// Function templates are not supported yet
+
+#[inline(always)]
+pub fn AlsoTemplateOverload() {
+ unsafe { crate::detail::__rust_thunk___Z20AlsoTemplateOverloadv() }
+}
+
+// rs_bindings_from_cc/test/golden/overloads.h;l=26
+// Error while generating bindings for item 'AlsoTemplateOverload':
+// Function templates are not supported yet
+
+// THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_OVERLOADS_H_
+
+#[::ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInstNSt3__u17integral_constantIbLb0EEE {
+ __non_field_data: [::std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+ forward_declare::symbol!("std::integral_constant<bool, false>"),
+ crate::__CcTemplateInstNSt3__u17integral_constantIbLb0EEE
+);
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, false>::std::integral_constant<bool, false>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, false>::std::integral_constant<bool, false>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, false>::integral_constant':
+// Parameter #0 is not supported: Unsupported type 'struct std::integral_constant<_Bool, false> &&': Unsupported type: && without lifetime
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, false>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, false>::operator=':
+// Parameter #0 is not supported: Unsupported type 'struct std::integral_constant<_Bool, false> &&': Unsupported type: && without lifetime
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=24
+// Error while generating bindings for item 'value_type':
+// Typedefs nested in classes are not supported yet
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=25
+// Error while generating bindings for item 'type':
+// Typedefs nested in classes are not supported yet
+
+// <unknown location>
+// Error while generating bindings for item 'std::integral_constant<bool, false>::operator bool':
+// TODO(b/248542210,b/248577708): as a temporary workaround for un-instantiable function templates, template functions from the STL cannot be instantiated in user crates
+
+// <unknown location>
+// Error while generating bindings for item 'std::integral_constant<bool, false>::operator()':
+// TODO(b/248542210,b/248577708): as a temporary workaround for un-instantiable function templates, template functions from the STL cannot be instantiated in user crates
+
+#[::ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInstNSt3__u17integral_constantIbLb1EEE {
+ __non_field_data: [::std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+ forward_declare::symbol!("std::integral_constant<bool, true>"),
+ crate::__CcTemplateInstNSt3__u17integral_constantIbLb1EEE
+);
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, true>::std::integral_constant<bool, true>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, true>::std::integral_constant<bool, true>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, true>::integral_constant':
+// Parameter #0 is not supported: Unsupported type 'struct std::integral_constant<_Bool, true> &&': Unsupported type: && without lifetime
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, true>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=21
+// Error while generating bindings for item 'std::integral_constant<bool, true>::operator=':
+// Parameter #0 is not supported: Unsupported type 'struct std::integral_constant<_Bool, true> &&': Unsupported type: && without lifetime
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=24
+// Error while generating bindings for item 'value_type':
+// Typedefs nested in classes are not supported yet
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/integral_constant.h;l=25
+// Error while generating bindings for item 'type':
+// Typedefs nested in classes are not supported yet
+
+// <unknown location>
+// Error while generating bindings for item 'std::integral_constant<bool, true>::operator bool':
+// TODO(b/248542210,b/248577708): as a temporary workaround for un-instantiable function templates, template functions from the STL cannot be instantiated in user crates
+
+// <unknown location>
+// Error while generating bindings for item 'std::integral_constant<bool, true>::operator()':
+// TODO(b/248542210,b/248577708): as a temporary workaround for un-instantiable function templates, template functions from the STL cannot be instantiated in user crates
+
+#[::ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInstNSt3__u11__type_listINS_12__align_typeIhEENS0_INS1_ItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEEEE
+{
+ __non_field_data: [::std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(forward_declare::symbol!("std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>"),crate::__CcTemplateInstNSt3__u11__type_listINS_12__align_typeIhEENS0_INS1_ItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEEEE);
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/type_list.h;l=22
+// Error while generating bindings for item 'std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>::std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/type_list.h;l=22
+// Error while generating bindings for item 'std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>::std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/type_list.h;l=22
+// Error while generating bindings for item 'std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>::__type_list':
+// Parameter #0 is not supported: Unsupported type 'struct std::__type_list<struct std::__align_type<unsigned char>, struct std::__type_list<struct std::__align_type<unsigned short>, struct std::__type_list<struct std::__align_type<unsigned int>, struct std::__type_list<struct std::__align_type<unsigned long>, struct std::__type_list<struct std::__align_type<unsigned long long>, struct std::__type_list<struct std::__align_type<double>, struct std::__type_list<struct std::__align_type<long double>, struct std::__type_list<struct std::__align_type<struct std::__struct_double>, struct std::__type_list<struct std::__align_type<struct std::__struct_double4>, struct std::__type_list<struct std::__align_type<int *>, struct std::__nat> > > > > > > > > > &&': Unsupported type: && without lifetime
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/type_list.h;l=22
+// Error while generating bindings for item 'std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/type_list.h;l=22
+// Error while generating bindings for item 'std::__type_list<std::__align_type<unsigned char>, std::__type_list<std::__align_type<unsigned short>, std::__type_list<std::__align_type<unsigned int>, std::__type_list<std::__align_type<unsigned long>, std::__type_list<std::__align_type<unsigned long long>, std::__type_list<std::__align_type<double>, std::__type_list<std::__align_type<long double>, std::__type_list<std::__align_type<std::__struct_double>, std::__type_list<std::__align_type<std::__struct_double4>, std::__type_list<std::__align_type<int *>, std::__nat>>>>>>>>>>::operator=':
+// Parameter #0 is not supported: Unsupported type 'struct std::__type_list<struct std::__align_type<unsigned char>, struct std::__type_list<struct std::__align_type<unsigned short>, struct std::__type_list<struct std::__align_type<unsigned int>, struct std::__type_list<struct std::__align_type<unsigned long>, struct std::__type_list<struct std::__align_type<unsigned long long>, struct std::__type_list<struct std::__align_type<double>, struct std::__type_list<struct std::__align_type<long double>, struct std::__type_list<struct std::__align_type<struct std::__struct_double>, struct std::__type_list<struct std::__align_type<struct std::__struct_double4>, struct std::__type_list<struct std::__align_type<int *>, struct std::__nat> > > > > > > > > > &&': Unsupported type: && without lifetime
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/type_list.h;l=24
+// Error while generating bindings for item '_Head':
+// Typedefs nested in classes are not supported yet
+
+// google3/nowhere/llvm/toolchain/include/c++/v1/__type_traits/type_list.h;l=25
+// Error while generating bindings for item '_Tail':
+// Typedefs nested in classes are not supported yet
+
+forward_declare::forward_declare!(pub __CcTemplateInstNSt3__u11__type_listINS_12__align_typeItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEE = forward_declare::symbol!("__CcTemplateInstNSt3__u11__type_listINS_12__align_typeItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEE"));
+
+forward_declare::forward_declare!(pub __CcTemplateInstNSt3__u12__align_typeIhEE = forward_declare::symbol!("__CcTemplateInstNSt3__u12__align_typeIhEE"));
+
+mod detail {
+ #[allow(unused_imports)]
+ use super::*;
+ extern "C" {
+ pub(crate) fn __rust_thunk___Z20AlsoTemplateOverloadv();
+ }
+}
+
+const _: () = assert!(::std::mem::size_of::<Option<&i32>>() == ::std::mem::size_of::<&i32>());
+
+const _: () = assert!(
+ ::std::mem::size_of::<crate::__CcTemplateInstNSt3__u17integral_constantIbLb0EEE>() == 1
+);
+const _: () = assert!(
+ ::std::mem::align_of::<crate::__CcTemplateInstNSt3__u17integral_constantIbLb0EEE>() == 1
+);
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::__CcTemplateInstNSt3__u17integral_constantIbLb0EEE: Copy
+ );
+};
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::__CcTemplateInstNSt3__u17integral_constantIbLb0EEE: Drop
+ );
+};
+
+const _: () = assert!(
+ ::std::mem::size_of::<crate::__CcTemplateInstNSt3__u17integral_constantIbLb1EEE>() == 1
+);
+const _: () = assert!(
+ ::std::mem::align_of::<crate::__CcTemplateInstNSt3__u17integral_constantIbLb1EEE>() == 1
+);
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::__CcTemplateInstNSt3__u17integral_constantIbLb1EEE: Copy
+ );
+};
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::__CcTemplateInstNSt3__u17integral_constantIbLb1EEE: Drop
+ );
+};
+
+const _:()=assert!(::std::mem::size_of::<crate::__CcTemplateInstNSt3__u11__type_listINS_12__align_typeIhEENS0_INS1_ItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEEEE>()==1);
+const _:()=assert!(::std::mem::align_of::<crate::__CcTemplateInstNSt3__u11__type_listINS_12__align_typeIhEENS0_INS1_ItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEEEE>()==1);
+const _: () = {
+ static_assertions::assert_not_impl_any!(crate::__CcTemplateInstNSt3__u11__type_listINS_12__align_typeIhEENS0_INS1_ItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEEEE:Copy);
+};
+const _: () = {
+ static_assertions::assert_not_impl_any!(crate::__CcTemplateInstNSt3__u11__type_listINS_12__align_typeIhEENS0_INS1_ItEENS0_INS1_IjEENS0_INS1_ImEENS0_INS1_IyEENS0_INS1_IdEENS0_INS1_IeEENS0_INS1_INS_15__struct_doubleEEENS0_INS1_INS_16__struct_double4EEENS0_INS1_IPiEENS_5__natEEEEEEEEEEEEEEEEEEEEE:Drop);
+};
diff --git a/rs_bindings_from_cc/test/golden/overloads_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/overloads_rs_api_impl.cc
new file mode 100644
index 0000000..4cc2d37
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/overloads_rs_api_impl.cc
@@ -0,0 +1,71 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include <cstddef>
+#include <memory>
+
+#include "rs_bindings_from_cc/support/cxx20_backports.h"
+#include "rs_bindings_from_cc/support/offsetof.h"
+#include "rs_bindings_from_cc/test/golden/overloads.h"
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wthread-safety-analysis"
+extern "C" void __rust_thunk___Z20AlsoTemplateOverloadv() {
+ AlsoTemplateOverload();
+}
+
+static_assert(sizeof(struct std::integral_constant<bool, false>) == 1);
+static_assert(alignof(struct std::integral_constant<bool, false>) == 1);
+
+static_assert(sizeof(struct std::integral_constant<bool, true>) == 1);
+static_assert(alignof(struct std::integral_constant<bool, true>) == 1);
+
+static_assert(
+ sizeof(struct std::__type_list<
+ std::__align_type<unsigned char>,
+ std::__type_list<
+ std::__align_type<unsigned short>,
+ std::__type_list<
+ std::__align_type<unsigned int>,
+ std::__type_list<
+ std::__align_type<unsigned long>,
+ std::__type_list<
+ std::__align_type<unsigned long long>,
+ std::__type_list<
+ std::__align_type<double>,
+ std::__type_list<
+ std::__align_type<long double>,
+ std::__type_list<
+ std::__align_type<std::__struct_double>,
+ std::__type_list<
+ std::__align_type<
+ std::__struct_double4>,
+ std::__type_list<
+ std::__align_type<int*>,
+ std::__nat>>>>>>>>>>) == 1);
+static_assert(
+ alignof(struct std::__type_list<
+ std::__align_type<unsigned char>,
+ std::__type_list<
+ std::__align_type<unsigned short>,
+ std::__type_list<
+ std::__align_type<unsigned int>,
+ std::__type_list<
+ std::__align_type<unsigned long>,
+ std::__type_list<
+ std::__align_type<unsigned long long>,
+ std::__type_list<
+ std::__align_type<double>,
+ std::__type_list<
+ std::__align_type<long double>,
+ std::__type_list<
+ std::__align_type<std::__struct_double>,
+ std::__type_list<
+ std::__align_type<
+ std::__struct_double4>,
+ std::__type_list<
+ std::__align_type<int*>,
+ std::__nat>>>>>>>>>>) == 1);
+
+#pragma clang diagnostic pop