Be more specific in our handling of explicit instantiations
In this CL:
1) we generate unsupported item for explicit class template instantiation declarations
2) we make explicit class template instantiation definitions work (the golden test for `templates.h` would not compile
PiperOrigin-RevId: 472972750
diff --git a/rs_bindings_from_cc/importers/BUILD b/rs_bindings_from_cc/importers/BUILD
index 0d6e914..15ba26c 100644
--- a/rs_bindings_from_cc/importers/BUILD
+++ b/rs_bindings_from_cc/importers/BUILD
@@ -24,6 +24,7 @@
"//rs_bindings_from_cc:ast_convert",
"//rs_bindings_from_cc:decl_importer",
"@llvm-project//clang:ast",
+ "@llvm-project//clang:basic",
"@llvm-project//clang:sema",
"@llvm-project//llvm:Support",
],
diff --git a/rs_bindings_from_cc/importers/cxx_record.cc b/rs_bindings_from_cc/importers/cxx_record.cc
index ca215a7..e3a7325 100644
--- a/rs_bindings_from_cc/importers/cxx_record.cc
+++ b/rs_bindings_from_cc/importers/cxx_record.cc
@@ -7,13 +7,13 @@
#include "absl/log/check.h"
#include "absl/log/die_if_null.h"
#include "absl/log/log.h"
-#include "absl/strings/match.h"
#include "rs_bindings_from_cc/ast_convert.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h"
#include "llvm/Support/ErrorHandling.h"
@@ -51,7 +51,7 @@
//
// This logic should go away once we start generating top level bindings for
// explicit class template specializations.
- if (specialization_decl->isExplicitSpecialization()) {
+ if (specialization_decl->isExplicitInstantiationOrSpecialization()) {
llvm::SmallString<128> storage;
llvm::raw_svector_ostream out(storage);
out << specialization_decl->getName();
@@ -143,8 +143,16 @@
if (auto* specialization_decl =
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
record_decl)) {
+ if (specialization_decl->getSpecializationKind() ==
+ clang::TSK_ExplicitInstantiationDeclaration) {
+ return ictx_.ImportUnsupportedItem(
+ record_decl,
+ "Explicit class template instantiation declarations are not handled "
+ "yet.");
+ }
+
is_implicit_class_template_specialization_decl =
- !specialization_decl->isExplicitSpecialization();
+ !specialization_decl->isExplicitInstantiationOrSpecialization();
rs_name = ictx_.GetMangledName(specialization_decl);
cc_name =
GetClassTemplateSpecializationCcName(ictx_.ctx_, specialization_decl);
diff --git a/rs_bindings_from_cc/ir_from_cc_test.rs b/rs_bindings_from_cc/ir_from_cc_test.rs
index ecb9037..bb2df15 100644
--- a/rs_bindings_from_cc/ir_from_cc_test.rs
+++ b/rs_bindings_from_cc/ir_from_cc_test.rs
@@ -143,10 +143,22 @@
}
#[test]
-fn test_dont_import_unused_class_template_or_specialization() {
- let ir = ir_from_cc("template <class T> struct Template{}; template<> struct Template<int>{};")
- .unwrap();
- assert_ir_not_matches!(ir, quote! { Record { ... "Template" ... } });
+fn test_explicit_class_template_instantiation_declaration_not_supported_yet() {
+ let ir = ir_from_cc(
+ "
+ template <class T> struct MyTemplate{};
+ extern template struct MyTemplate<int>;
+ ",
+ )
+ .unwrap();
+ assert_ir_not_matches!(ir, quote! { Record });
+ assert_ir_matches!(
+ ir,
+ quote! { UnsupportedItem {
+ name: "MyTemplate",
+ message: "Explicit class template instantiation declarations are not handled yet." ...
+ }}
+ );
}
#[test]
@@ -696,8 +708,22 @@
let type_mapping: HashMap<_, _> = fields
.map(|f| {
(
- f.type_.as_ref().unwrap().cc_type.name.as_ref().unwrap().as_str(),
- f.type_.as_ref().unwrap().rs_type.name.as_ref().unwrap().as_str(),
+ f.type_
+ .as_ref()
+ .unwrap()
+ .cc_type
+ .name
+ .as_ref()
+ .unwrap()
+ .as_str(),
+ f.type_
+ .as_ref()
+ .unwrap()
+ .rs_type
+ .name
+ .as_ref()
+ .unwrap()
+ .as_str(),
)
})
.collect();
@@ -869,7 +895,7 @@
}
#[test]
-fn test_typedef_of_fully_instantiated_template() -> Result<()> {
+fn test_typedef_of_full_template_specialization() -> Result<()> {
let ir = ir_from_cc(
r#" #pragma clang lifetime_elision
namespace test_namespace_bindings {
@@ -887,7 +913,7 @@
using MyTypeAlias = MyStruct<int>;
}"#,
)?;
- // Instantiation of the struct template:
+ // Instantiation of MyStruct<int> specialization:
assert_ir_matches!(
ir,
quote! {
@@ -939,7 +965,7 @@
}
}
);
- // Member function of the struct template instantiation:
+ // Member function of the MyTemplate<int> specialization:
assert_ir_matches!(
ir,
quote! {
@@ -996,7 +1022,7 @@
using MyTypeAlias = MyStruct<int>;
}"#,
)?;
- // Instantiation of the struct template based on the specialization for T=int:
+ // Instantiation of the explicit MyStruct<int> specialization:
assert_ir_matches!(
ir,
quote! {
@@ -1028,7 +1054,7 @@
// assert_eq!(1, ir.top_level_item_ids().filter(|&&id| id ==
// record_id).count());
- // Instance method inside the struct template:
+ // Instance method inside the explicit MyStruct<int> specialization:
assert_ir_matches!(
ir,
quote! {
@@ -1049,7 +1075,7 @@
}
#[test]
-fn test_multiple_typedefs_to_same_template() -> Result<()> {
+fn test_multiple_typedefs_to_same_specialization() -> Result<()> {
let ir = ir_from_cc(
r#" #pragma clang lifetime_elision
template <typename T>
@@ -1143,6 +1169,28 @@
}
#[test]
+fn test_explicit_class_template_instantiation_definitions_are_imported() {
+ let ir = ir_from_cc(
+ "
+ namespace my_namespace {
+ template <class T> struct MyTemplate{};
+ template struct MyTemplate<int>;
+ }
+ ",
+ )
+ .unwrap();
+ assert_ir_matches!(
+ ir,
+ quote! { Record {
+ rs_name: "__CcTemplateInstN12my_namespace10MyTemplateIiEE", ...
+ cc_name: "MyTemplate<int>", ...
+ owning_target: BazelLabel("//test:testing_target"), ...
+ enclosing_namespace_id: Some(...), ...
+ }}
+ );
+}
+
+#[test]
fn test_templates_inheritance() -> Result<()> {
let ir = ir_from_cc(
r#" #pragma clang lifetime_elision
@@ -2070,7 +2118,10 @@
fn test_typedef_nested_in_record_not_supported() {
let ir = ir_from_cc("struct S { typedef int MyTypedefDecl; };").unwrap();
assert_strings_contain(
- ir.unsupported_items().map(|i| i.name.as_str()).collect_vec().as_slice(),
+ ir.unsupported_items()
+ .map(|i| i.name.as_str())
+ .collect_vec()
+ .as_slice(),
"S::MyTypedefDecl",
);
}
@@ -2652,7 +2703,10 @@
// once we start importing nested structs.
let ir = ir_from_cc("struct X { struct Y {}; };")?;
assert_strings_contain(
- ir.unsupported_items().map(|i| i.name.as_str()).collect_vec().as_slice(),
+ ir.unsupported_items()
+ .map(|i| i.name.as_str())
+ .collect_vec()
+ .as_slice(),
"X::Y",
);
Ok(())
@@ -3491,7 +3545,7 @@
}
#[test]
-fn test_incomplete_record_has_rs_name() {
+fn test_forward_declared_specialization_has_rs_name() {
let ir = ir_from_cc(
r#"
namespace test_namespace_bindings {
diff --git a/rs_bindings_from_cc/test/golden/templates.h b/rs_bindings_from_cc/test/golden/templates.h
index 816f32b..ebdac54 100644
--- a/rs_bindings_from_cc/test/golden/templates.h
+++ b/rs_bindings_from_cc/test/golden/templates.h
@@ -49,8 +49,31 @@
T t;
};
+// Explicit class template specialization with definition should not be imported
+// unless also instantiated.
+// TODO(b/245680028): `MyStruct<bool>` should not be imported.
+template <>
+struct MyStruct<bool> {};
+
+// Explicit class template specialization with definition should be imported
+// even when not instantiated if there is a type alias for it.
template <>
struct MyStruct<char> {};
+using MyCharStruct = MyStruct<char>;
+
+// Forward declared explicit class template specialization should be imported
+// so the forward declaration code is generated (`forward_declare!`).
+template <>
+struct MyStruct<int>;
+
+// Explicit class template instantiation definition is imported similarly to
+// how implicit typedeffed instantiations are.
+template class MyStruct<float>;
+
+// Explicit class template instantiation declaration is not handled (yet?)
+// TODO(b/245467707): Consider handling these as a build speed/ergonomic
+// optimization.
+extern template class MyStruct<double>;
} // namespace test_namespace_bindings
diff --git a/rs_bindings_from_cc/test/golden/templates_rs_api.rs b/rs_bindings_from_cc/test/golden/templates_rs_api.rs
index e7ada0d..8a80218 100644
--- a/rs_bindings_from_cc/test/golden/templates_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/templates_rs_api.rs
@@ -130,6 +130,42 @@
// Error while generating bindings for item 'test_namespace_bindings::MyStruct':
// Class templates are not supported yet
+ /// Explicit class template specialization with definition should not be imported
+ /// unless also instantiated.
+ /// TODO(b/245680028): `MyStruct<bool>` should not be imported.
+ #[::ctor::recursively_pinned]
+ #[repr(C)]
+ pub struct __CcTemplateInstN23test_namespace_bindings8MyStructIbEE {
+ __non_field_data: [::std::mem::MaybeUninit<u8>; 1],
+ }
+ forward_declare::unsafe_define!(
+ forward_declare::symbol!("MyStruct<bool>"),
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE
+ );
+
+ impl ::ctor::CtorNew<()> for __CcTemplateInstN23test_namespace_bindings8MyStructIbEE {
+ type CtorType = impl ::ctor::Ctor<Output = Self>;
+ #[inline(always)]
+ fn ctor_new(args: ()) -> Self::CtorType {
+ let () = args;
+ unsafe {
+ ::ctor::FnCtor::new(move|dest: ::std::pin::Pin<&mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>>|{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(::std::pin::Pin::into_inner_unchecked(dest)); })
+ }
+ }
+ }
+
+ impl<'b>::ctor::CtorNew<&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>for __CcTemplateInstN23test_namespace_bindings8MyStructIbEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE)->Self::CtorType{ let __param_0=args;unsafe{ ::ctor::FnCtor::new(move|dest: ::std::pin::Pin<&mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>>|{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1ERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(::std::pin::Pin::into_inner_unchecked(dest),__param_0); }) } } }
+ impl<'b>::ctor::CtorNew<(&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE,)>for __CcTemplateInstN23test_namespace_bindings8MyStructIbEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args:(&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE,))->Self::CtorType{ let(arg,)=args;<Self as::ctor::CtorNew<&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>>::ctor_new(arg) } }
+
+ impl<'b>::ctor::CtorNew<::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>>for __CcTemplateInstN23test_namespace_bindings8MyStructIbEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>)->Self::CtorType{ let __param_0=args;unsafe{ ::ctor::FnCtor::new(move|dest: ::std::pin::Pin<&mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>>|{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1EOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(::std::pin::Pin::into_inner_unchecked(dest),__param_0); }) } } }
+ impl<'b>::ctor::CtorNew<(::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,)>for __CcTemplateInstN23test_namespace_bindings8MyStructIbEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args:(::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,))->Self::CtorType{ let(arg,)=args;<Self as::ctor::CtorNew<::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>>>::ctor_new(arg) } }
+
+ impl<'b>::ctor::Assign<&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>for __CcTemplateInstN23test_namespace_bindings8MyStructIbEE{ #[inline(always)]fn assign<'a>(self: ::std::pin::Pin<&'a mut Self>,__param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE){ unsafe{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIbEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(self,__param_0); } } }
+
+ impl<'b>::ctor::Assign<::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>>for __CcTemplateInstN23test_namespace_bindings8MyStructIbEE{ #[inline(always)]fn assign<'a>(self: ::std::pin::Pin<&'a mut Self>,__param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>){ unsafe{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIbEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(self,__param_0); } } }
+
+ /// Explicit class template specialization with definition should be imported
+ /// even when not instantiated if there is a type alias for it.
#[::ctor::recursively_pinned]
#[repr(C)]
pub struct __CcTemplateInstN23test_namespace_bindings8MyStructIcEE {
@@ -160,11 +196,53 @@
impl<'b>::ctor::Assign<&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>for __CcTemplateInstN23test_namespace_bindings8MyStructIcEE{ #[inline(always)]fn assign<'a>(self: ::std::pin::Pin<&'a mut Self>,__param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE){ unsafe{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIcEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(self,__param_0); } } }
impl<'b>::ctor::Assign<::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>>for __CcTemplateInstN23test_namespace_bindings8MyStructIcEE{ #[inline(always)]fn assign<'a>(self: ::std::pin::Pin<&'a mut Self>,__param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>){ unsafe{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIcEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(self,__param_0); } } }
+
+ pub type MyCharStruct =
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE;
+
+ forward_declare::forward_declare!(pub __CcTemplateInstN23test_namespace_bindings8MyStructIiEE = forward_declare::symbol!("__CcTemplateInstN23test_namespace_bindings8MyStructIiEE"));
+
+ /// Explicit class template instantiation definition is imported similarly to
+ /// how implicit typedeffed instantiations are.
+ #[::ctor::recursively_pinned]
+ #[repr(C)]
+ pub struct __CcTemplateInstN23test_namespace_bindings8MyStructIfEE {
+ pub t: f32,
+ }
+ forward_declare::unsafe_define!(
+ forward_declare::symbol!("MyStruct<float>"),
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE
+ );
+
+ impl ::ctor::CtorNew<()> for __CcTemplateInstN23test_namespace_bindings8MyStructIfEE {
+ type CtorType = impl ::ctor::Ctor<Output = Self>;
+ #[inline(always)]
+ fn ctor_new(args: ()) -> Self::CtorType {
+ let () = args;
+ unsafe {
+ ::ctor::FnCtor::new(move|dest: ::std::pin::Pin<&mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>>|{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(::std::pin::Pin::into_inner_unchecked(dest)); })
+ }
+ }
+ }
+
+ impl<'b>::ctor::CtorNew<&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>for __CcTemplateInstN23test_namespace_bindings8MyStructIfEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE)->Self::CtorType{ let __param_0=args;unsafe{ ::ctor::FnCtor::new(move|dest: ::std::pin::Pin<&mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>>|{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1ERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(::std::pin::Pin::into_inner_unchecked(dest),__param_0); }) } } }
+ impl<'b>::ctor::CtorNew<(&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE,)>for __CcTemplateInstN23test_namespace_bindings8MyStructIfEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args:(&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE,))->Self::CtorType{ let(arg,)=args;<Self as::ctor::CtorNew<&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>>::ctor_new(arg) } }
+
+ impl<'b>::ctor::CtorNew<::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>>for __CcTemplateInstN23test_namespace_bindings8MyStructIfEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>)->Self::CtorType{ let __param_0=args;unsafe{ ::ctor::FnCtor::new(move|dest: ::std::pin::Pin<&mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>>|{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1EOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(::std::pin::Pin::into_inner_unchecked(dest),__param_0); }) } } }
+ impl<'b>::ctor::CtorNew<(::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,)>for __CcTemplateInstN23test_namespace_bindings8MyStructIfEE{ type CtorType=impl::ctor::Ctor<Output=Self>+::ctor::Captures<'b>;#[inline(always)]fn ctor_new(args:(::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,))->Self::CtorType{ let(arg,)=args;<Self as::ctor::CtorNew<::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>>>::ctor_new(arg) } }
+
+ impl<'b>::ctor::Assign<&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>for __CcTemplateInstN23test_namespace_bindings8MyStructIfEE{ #[inline(always)]fn assign<'a>(self: ::std::pin::Pin<&'a mut Self>,__param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE){ unsafe{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIfEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(self,__param_0); } } }
+
+ impl<'b>::ctor::Assign<::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>>for __CcTemplateInstN23test_namespace_bindings8MyStructIfEE{ #[inline(always)]fn assign<'a>(self: ::std::pin::Pin<&'a mut Self>,__param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>){ unsafe{ crate::detail::__rust_thunk___ZN23test_namespace_bindings8MyStructIfEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(self,__param_0); } } }
+
+ // rs_bindings_from_cc/test/golden/templates.h;l=76
+ // Error while generating bindings for item 'test_namespace_bindings::MyStruct':
+ // Explicit class template instantiation declarations are not handled yet.
}
// namespace test_namespace_bindings
-// rs_bindings_from_cc/test/golden/templates.h;l=57
+// rs_bindings_from_cc/test/golden/templates.h;l=80
// Error while generating bindings for item 'MyTopLevelTemplate':
// Class templates are not supported yet
@@ -183,7 +261,7 @@
}
pub mod template_template_params {
- // rs_bindings_from_cc/test/golden/templates.h;l=72
+ // rs_bindings_from_cc/test/golden/templates.h;l=95
// Error while generating bindings for item 'template_template_params::Policy':
// Class templates are not supported yet
@@ -218,7 +296,7 @@
impl<'b>::ctor::Assign<::ctor::RvalueReference<'b,crate::template_template_params::__CcTemplateInstN24template_template_params6PolicyIiEE>>for __CcTemplateInstN24template_template_params6PolicyIiEE{ #[inline(always)]fn assign<'a>(self: ::std::pin::Pin<&'a mut Self>,__param_0: ::ctor::RvalueReference<'b,crate::template_template_params::__CcTemplateInstN24template_template_params6PolicyIiEE>){ unsafe{ crate::detail::__rust_thunk___ZN24template_template_params6PolicyIiEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(self,__param_0); } } }
- // rs_bindings_from_cc/test/golden/templates.h;l=82
+ // rs_bindings_from_cc/test/golden/templates.h;l=105
// Error while generating bindings for item 'template_template_params::MyTemplate':
// Class templates are not supported yet
@@ -228,11 +306,11 @@
// namespace template_template_params
-pub mod forward_declared_template { // rs_bindings_from_cc/test/golden/templates.h;l=100
+pub mod forward_declared_template { // rs_bindings_from_cc/test/golden/templates.h;l=123
// Error while generating bindings for item 'forward_declared_template::ForwardDeclaredTemplate':
// Class templates are not supported yet
- // rs_bindings_from_cc/test/golden/templates.h;l=103
+ // rs_bindings_from_cc/test/golden/templates.h;l=126
// Error while generating bindings for item 'forward_declared_template::TypeAliasToForwardDeclaredTemplate':
// Unsupported type 'ForwardDeclaredTemplate<int>': 'ForwardDeclaredTemplate<int>' template specialization is incomplete
}
@@ -620,11 +698,11 @@
}
}
-// rs_bindings_from_cc/test/golden/templates.h;l=58
+// rs_bindings_from_cc/test/golden/templates.h;l=81
// Error while generating bindings for item 'MyTopLevelTemplate<test_namespace_bindings::TemplateParam>::operator=':
// operator= for Unpin types is not yet supported.
-// rs_bindings_from_cc/test/golden/templates.h;l=58
+// rs_bindings_from_cc/test/golden/templates.h;l=81
// Error while generating bindings for item 'MyTopLevelTemplate<test_namespace_bindings::TemplateParam>::operator=':
// operator= for Unpin types is not yet supported.
@@ -798,6 +876,27 @@
__this: &'a mut ::std::mem::MaybeUninit<crate::test_namespace_bindings::TemplateParam>,
__param_0: ::ctor::RvalueReference<'b, crate::test_namespace_bindings::TemplateParam>,
);
+ pub(crate) fn __rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
+ 'a,
+ >(
+ __this:&'a mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,
+ );
+ pub(crate) fn __rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1ERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
+ 'a,
+ 'b,
+ >(
+ __this:&'a mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,
+ __param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE,
+ );
+ pub(crate) fn __rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1EOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
+ 'a,
+ 'b,
+ >(
+ __this:&'a mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,
+ __param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,
+ );
+ pub(crate)fn __rust_thunk___ZN23test_namespace_bindings8MyStructIbEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<'a,'b>(__this: ::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,__param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE)->::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>;
+ pub(crate)fn __rust_thunk___ZN23test_namespace_bindings8MyStructIbEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<'a,'b>(__this: ::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>,__param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>)->::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE>;
pub(crate) fn __rust_thunk___ZN23test_namespace_bindings8MyStructIcEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
'a,
>(
@@ -819,6 +918,27 @@
);
pub(crate)fn __rust_thunk___ZN23test_namespace_bindings8MyStructIcEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<'a,'b>(__this: ::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>,__param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE)->::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>;
pub(crate)fn __rust_thunk___ZN23test_namespace_bindings8MyStructIcEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<'a,'b>(__this: ::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>,__param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>)->::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE>;
+ pub(crate) fn __rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
+ 'a,
+ >(
+ __this:&'a mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,
+ );
+ pub(crate) fn __rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1ERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
+ 'a,
+ 'b,
+ >(
+ __this:&'a mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,
+ __param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE,
+ );
+ pub(crate) fn __rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1EOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
+ 'a,
+ 'b,
+ >(
+ __this:&'a mut::std::mem::MaybeUninit<crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,
+ __param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,
+ );
+ pub(crate)fn __rust_thunk___ZN23test_namespace_bindings8MyStructIfEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<'a,'b>(__this: ::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,__param_0:&'b crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE)->::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>;
+ pub(crate)fn __rust_thunk___ZN23test_namespace_bindings8MyStructIfEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<'a,'b>(__this: ::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>,__param_0: ::ctor::RvalueReference<'b,crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>)->::std::pin::Pin<&'a mut crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE>;
#[link_name = "_Z36processForwardDeclaredSpecializationP18MyTopLevelTemplateIiE"]
pub(crate) fn __rust_thunk___Z36processForwardDeclaredSpecializationP18MyTopLevelTemplateIiE<
'a,
@@ -1051,6 +1171,28 @@
};
const _: () = assert!(
::std::mem::size_of::<
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE,
+ >() == 1
+);
+const _: () = assert!(
+ ::std::mem::align_of::<
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE,
+ >() == 1
+);
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE:
+ Copy
+ );
+};
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIbEE:
+ Drop
+ );
+};
+const _: () = assert!(
+ ::std::mem::size_of::<
crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIcEE,
>() == 1
);
@@ -1071,6 +1213,34 @@
Drop
);
};
+const _: () = assert!(
+ ::std::mem::size_of::<
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE,
+ >() == 4
+);
+const _: () = assert!(
+ ::std::mem::align_of::<
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE,
+ >() == 4
+);
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE:
+ Copy
+ );
+};
+const _: () = {
+ static_assertions::assert_not_impl_any!(
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE:
+ Drop
+ );
+};
+const _: () = assert!(
+ memoffset::offset_of!(
+ crate::test_namespace_bindings::__CcTemplateInstN23test_namespace_bindings8MyStructIfEE,
+ t
+ ) == 0
+);
const _: () = assert!(
::std::mem::size_of::<
diff --git a/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
index fa42c48..c7cfb84 100644
--- a/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
@@ -124,6 +124,33 @@
crubit::construct_at(__this, std::move(*__param_0));
}
extern "C" void
+__rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<bool>* __this) {
+ crubit::construct_at(__this);
+}
+extern "C" void
+__rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1ERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<bool>* __this,
+ const struct test_namespace_bindings::MyStruct<bool>* __param_0) {
+ crubit::construct_at(__this, *__param_0);
+}
+extern "C" void
+__rust_thunk___ZN23test_namespace_bindings8MyStructIbEC1EOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<bool>* __this,
+ struct test_namespace_bindings::MyStruct<bool>* __param_0) {
+ crubit::construct_at(__this, std::move(*__param_0));
+}
+extern "C" struct test_namespace_bindings::MyStruct<bool>*
+__rust_thunk___ZN23test_namespace_bindings8MyStructIbEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<bool>* __this,
+ const struct test_namespace_bindings::MyStruct<bool>* __param_0) {
+ return &__this->operator=(*__param_0);
+} extern "C" struct test_namespace_bindings::MyStruct<bool>*
+__rust_thunk___ZN23test_namespace_bindings8MyStructIbEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<bool>* __this,
+ struct test_namespace_bindings::MyStruct<bool>* __param_0) {
+ return &__this->operator=(std::move(*__param_0));
+} extern "C" void
__rust_thunk___ZN23test_namespace_bindings8MyStructIcEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
struct test_namespace_bindings::MyStruct<char>* __this) {
crubit::construct_at(__this);
@@ -151,6 +178,33 @@
struct test_namespace_bindings::MyStruct<char>* __param_0) {
return &__this->operator=(std::move(*__param_0));
} extern "C" void
+__rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<float>* __this) {
+ crubit::construct_at(__this);
+}
+extern "C" void
+__rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1ERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<float>* __this,
+ const struct test_namespace_bindings::MyStruct<float>* __param_0) {
+ crubit::construct_at(__this, *__param_0);
+}
+extern "C" void
+__rust_thunk___ZN23test_namespace_bindings8MyStructIfEC1EOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<float>* __this,
+ struct test_namespace_bindings::MyStruct<float>* __param_0) {
+ crubit::construct_at(__this, std::move(*__param_0));
+}
+extern "C" struct test_namespace_bindings::MyStruct<float>*
+__rust_thunk___ZN23test_namespace_bindings8MyStructIfEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<float>* __this,
+ const struct test_namespace_bindings::MyStruct<float>* __param_0) {
+ return &__this->operator=(*__param_0);
+} extern "C" struct test_namespace_bindings::MyStruct<float>*
+__rust_thunk___ZN23test_namespace_bindings8MyStructIfEaSEOS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
+ struct test_namespace_bindings::MyStruct<float>* __this,
+ struct test_namespace_bindings::MyStruct<float>* __param_0) {
+ return &__this->operator=(std::move(*__param_0));
+} extern "C" void
__rust_thunk___ZN18MyTopLevelTemplateIN23test_namespace_bindings13TemplateParamEEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc(
struct MyTopLevelTemplate<test_namespace_bindings::TemplateParam>* __this) {
crubit::construct_at(__this);
@@ -291,9 +345,17 @@
struct test_namespace_bindings::TemplateWithTwoParams<int, float>) ==
4);
+static_assert(sizeof(struct test_namespace_bindings::MyStruct<bool>) == 1);
+static_assert(alignof(struct test_namespace_bindings::MyStruct<bool>) == 1);
+
static_assert(sizeof(struct test_namespace_bindings::MyStruct<char>) == 1);
static_assert(alignof(struct test_namespace_bindings::MyStruct<char>) == 1);
+static_assert(sizeof(struct test_namespace_bindings::MyStruct<float>) == 4);
+static_assert(alignof(struct test_namespace_bindings::MyStruct<float>) == 4);
+static_assert(
+ CRUBIT_OFFSET_OF(t, struct test_namespace_bindings::MyStruct<float>) == 0);
+
static_assert(
sizeof(struct MyTopLevelTemplate<test_namespace_bindings::TemplateParam>) ==
1);