Really bad support for struct types as types (in member variables, parameters, etc.) :)
This is necessary in order to support member functions (including special member functions), so that their `this` parameter can be represented.
PiperOrigin-RevId: 402912882
diff --git a/rs_bindings_from_cc/ast_visitor.cc b/rs_bindings_from_cc/ast_visitor.cc
index f88f28c..03618a8 100644
--- a/rs_bindings_from_cc/ast_visitor.cc
+++ b/rs_bindings_from_cc/ast_visitor.cc
@@ -72,6 +72,26 @@
success = false;
continue;
}
+
+ if (const clang::RecordType* record_type =
+ llvm::dyn_cast<clang::RecordType>(param->getType())) {
+ if (clang::RecordDecl* record_decl =
+ llvm::dyn_cast<clang::RecordDecl>(record_type->getDecl())) {
+ // TODO(b/200067242): non-trivial_abi structs, when passed by value,
+ // have a different representation which needs special support. We
+ // currently do not support it.
+ if (!record_decl->canPassInRegisters()) {
+ ir_.items.push_back(UnsupportedItem{
+ .name = function_decl->getQualifiedNameAsString(),
+ .message = absl::Substitute("Non-trivial_abi type '$0' is not "
+ "supported by value as a parameter",
+ param->getType().getAsString()),
+ .source_loc = ConvertSourceLoc(param->getBeginLoc())});
+ success = false;
+ }
+ }
+ }
+
std::optional<Identifier> param_name = GetTranslatedIdentifier(param);
if (!param_name.has_value()) {
ir_.items.push_back(UnsupportedItem{
@@ -84,6 +104,27 @@
params.push_back({*param_type, *std::move(param_name)});
}
+ if (const clang::RecordType* record_return_type =
+ llvm::dyn_cast<clang::RecordType>(function_decl->getReturnType())) {
+ if (clang::RecordDecl* record_decl =
+ llvm::dyn_cast<clang::RecordDecl>(record_return_type->getDecl())) {
+ // TODO(b/200067242): non-trivial_abi structs, when passed by value,
+ // have a different representation which needs special support. We
+ // currently do not support it.
+ if (!record_decl->canPassInRegisters()) {
+ ir_.items.push_back(UnsupportedItem{
+ .name = function_decl->getQualifiedNameAsString(),
+ .message =
+ absl::Substitute("Non-trivial_abi type '$0' is not supported "
+ "by value as a return type",
+ function_decl->getReturnType().getAsString()),
+ .source_loc =
+ ConvertSourceLoc(function_decl->getReturnTypeSourceRange())});
+ success = false;
+ }
+ }
+ }
+
auto return_type = ConvertType(function_decl->getReturnType());
if (!return_type.ok()) {
ir_.items.push_back(UnsupportedItem{
@@ -267,6 +308,10 @@
.column = sm.getSpellingColumnNumber(loc)};
}
+SourceLoc AstVisitor::ConvertSourceLoc(clang::SourceRange range) const {
+ return ConvertSourceLoc(range.getBegin());
+}
+
absl::StatusOr<MappedType> AstVisitor::ConvertType(
clang::QualType qual_type) const {
std::optional<MappedType> type = std::nullopt;
@@ -310,6 +355,15 @@
}
}
}
+ } else if (const clang::TagType* tag_type =
+ qual_type->getAs<clang::TagType>()) {
+ // TODO(b/202692734): If tag_type is un-importable, fail here.
+ clang::TagDecl* tag_decl = tag_type->getDecl();
+
+ if (std::optional<Identifier> id = GetTranslatedIdentifier(tag_decl)) {
+ std::string ident(id->Ident());
+ return MappedType::Simple(ident, ident);
+ }
}
if (!type.has_value()) {
diff --git a/rs_bindings_from_cc/ast_visitor.h b/rs_bindings_from_cc/ast_visitor.h
index 2c7bf1c..c19b4c4 100644
--- a/rs_bindings_from_cc/ast_visitor.h
+++ b/rs_bindings_from_cc/ast_visitor.h
@@ -74,6 +74,7 @@
// Gets the doc comment of the declaration.
std::optional<std::string> GetComment(const clang::Decl* decl) const;
SourceLoc ConvertSourceLoc(clang::SourceLocation loc) const;
+ SourceLoc ConvertSourceLoc(clang::SourceRange range) const;
absl::StatusOr<MappedType> ConvertType(clang::QualType qual_type) const;
absl::Span<const absl::string_view> public_header_names_;
diff --git a/rs_bindings_from_cc/ast_visitor_test.cc b/rs_bindings_from_cc/ast_visitor_test.cc
index 67108af..7784057 100644
--- a/rs_bindings_from_cc/ast_visitor_test.cc
+++ b/rs_bindings_from_cc/ast_visitor_test.cc
@@ -301,9 +301,12 @@
}
TEST(AstVisitorTest, TrivialCopyConstructor) {
- absl::string_view file =
- "struct Implicit {};\n"
- "struct Defaulted { Defaulted(const Defaulted&) = default; };\n";
+ absl::string_view file = R"cc(
+ struct Implicit {};
+ struct Defaulted {
+ Defaulted(const Defaulted&) = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -313,36 +316,55 @@
}
TEST(AstVisitorTest, NontrivialCopyConstructor) {
- absl::string_view file = "struct Defined { Defined(const Defined&);};\n";
- // TODO(b/202113881): "struct MemberImplicit { Defined x; };\n"
- // TODO(b/202113881): "struct MemberDefaulted { MemberDefaulted(const
- // MemberDefaulted&) = default; Defined x; };\n"
+ absl::string_view file = R"cc(
+ struct Defined {
+ Defined(const Defined&);
+ };
+ struct MemberImplicit {
+ Defined x;
+ };
+ struct MemberDefaulted {
+ MemberDefaulted(const MemberDefaulted&) = default;
+ Defined x;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
-
std::vector<Record*> records = ir.get_items_if<Record>();
- EXPECT_THAT(records, SizeIs(1));
+ EXPECT_THAT(records, SizeIs(3));
EXPECT_THAT(records, Each(Pointee(CopyConstructor(DefinitionIs(
SpecialMemberFunc::Definition::kNontrivial)))));
}
TEST(AstVisitorTest, DeletedCopyConstructor) {
- absl::string_view file =
- "struct Deleted { Deleted(const Deleted&) = delete;};\n"
- // TODO(b/202113881): "struct DeletedByMember { Deleted x; };\n"
- "struct DeletedByCtorDef { DeletedByCtorDef(DeletedByCtorDef&&) {} };\n";
+ absl::string_view file = R"cc(
+ struct Deleted {
+ Deleted(const Deleted&) = delete;
+ };
+ struct DeletedByMember {
+ Deleted x;
+ };
+ struct DeletedByCtorDef {
+ DeletedByCtorDef(DeletedByCtorDef&&) {}
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
-
std::vector<Record*> records = ir.get_items_if<Record>();
- EXPECT_THAT(records, SizeIs(2));
+ EXPECT_THAT(records, SizeIs(3));
EXPECT_THAT(records, Each(Pointee(CopyConstructor(DefinitionIs(
SpecialMemberFunc::Definition::kDeleted)))));
}
TEST(AstVisitorTest, PublicCopyConstructor) {
- absl::string_view file =
- "class Implicit {};\n"
- "struct Defaulted { Defaulted(const Defaulted&) = default; };\n"
- "class Section { public: Section(const Section&) = default; };\n";
+ absl::string_view file = R"cc(
+ class Implicit {};
+ struct Defaulted {
+ Defaulted(const Defaulted&) = default;
+ };
+ class Section {
+ public:
+ Section(const Section&) = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -351,9 +373,15 @@
}
TEST(AstVisitorTest, PrivateCopyConstructor) {
- absl::string_view file =
- "class Defaulted { Defaulted(const Defaulted&) = default; };\n"
- "struct Section { private: Section(const Section&) = default; };\n";
+ absl::string_view file = R"cc(
+ class Defaulted {
+ Defaulted(const Defaulted&) = default;
+ };
+ struct Section {
+ private:
+ Section(const Section&) = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -362,9 +390,12 @@
}
TEST(AstVisitorTest, TrivialMoveConstructor) {
- absl::string_view file =
- "struct Implicit {};\n"
- "struct Defaulted { Defaulted(Defaulted&&) = default; };\n";
+ absl::string_view file = R"cc(
+ struct Implicit {};
+ struct Defaulted {
+ Defaulted(Defaulted&&) = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -374,37 +405,55 @@
}
TEST(AstVisitorTest, NontrivialMoveConstructor) {
- absl::string_view file = "struct Defined { Defined(Defined&&);};\n";
- // TODO(b/202113881): "struct MemberImplicit { Defined x; };\n"
- // TODO(b/202113881): "struct MemberDefaulted { MemberDefaulted(
- // MemberDefaulted&&) = default; Defined x; };\n"
+ absl::string_view file = R"cc(
+ struct Defined {
+ Defined(Defined&&);
+ };
+ struct MemberImplicit {
+ Defined x;
+ };
+ struct MemberDefaulted {
+ MemberDefaulted(MemberDefaulted&&) = default;
+ Defined x;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
-
std::vector<Record*> records = ir.get_items_if<Record>();
- EXPECT_THAT(records, SizeIs(1));
+ EXPECT_THAT(records, SizeIs(3));
EXPECT_THAT(records, Each(Pointee(MoveConstructor(DefinitionIs(
SpecialMemberFunc::Definition::kNontrivial)))));
}
TEST(AstVisitorTest, DeletedMoveConstructor) {
- absl::string_view file =
- "struct Deleted { Deleted(Deleted&&) = delete;};\n"
- // TODO(b/202113881): "struct DeletedByMember { Deleted x; };\n"
- "struct SuppressedByCtorDef {"
- " SuppressedByCtorDef(const SuppressedByCtorDef&) {}};\n";
+ absl::string_view file = R"cc(
+ struct Deleted {
+ Deleted(Deleted&&) = delete;
+ };
+ struct DeletedByMember {
+ Deleted x;
+ };
+ struct SuppressedByCtorDef {
+ SuppressedByCtorDef(const SuppressedByCtorDef&) {}
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
-
std::vector<Record*> records = ir.get_items_if<Record>();
- EXPECT_THAT(records, SizeIs(2));
+ EXPECT_THAT(records, SizeIs(3));
EXPECT_THAT(records, Each(Pointee(MoveConstructor(DefinitionIs(
SpecialMemberFunc::Definition::kDeleted)))));
}
TEST(AstVisitorTest, PublicMoveConstructor) {
- absl::string_view file =
- "class Implicit {};\n"
- "struct Defaulted { Defaulted(Defaulted&&) = default; };\n"
- "class Section { public: Section(Section&&) = default; };\n";
+ absl::string_view file = R"cc(
+ class Implicit {};
+ struct Defaulted {
+ Defaulted(Defaulted&&) = default;
+ };
+ class Section {
+ public:
+ Section(Section&&) = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -413,9 +462,15 @@
}
TEST(AstVisitorTest, PrivateMoveConstructor) {
- absl::string_view file =
- "class Defaulted { Defaulted(Defaulted&&) = default; };\n"
- "struct Section { private: Section(Section&&) = default; };\n";
+ absl::string_view file = R"cc(
+ class Defaulted {
+ Defaulted(Defaulted&&) = default;
+ };
+ struct Section {
+ private:
+ Section(Section&&) = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -424,9 +479,12 @@
}
TEST(AstVisitorTest, TrivialDestructor) {
- absl::string_view file =
- "struct Implicit {};\n"
- "struct Defaulted { ~Defaulted() = default; };\n";
+ absl::string_view file = R"cc(
+ struct Implicit {};
+ struct Defaulted {
+ ~Defaulted() = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -436,34 +494,54 @@
}
TEST(AstVisitorTest, NontrivialDestructor) {
- absl::string_view file = "struct Defined { ~Defined();};\n";
- // TODO(b/202113881): "struct MemberImplicit { Defined x; };\n"
- // TODO(b/202113881): "struct MemberDefaulted { ~MemberDefaulted() = default;
- // Defined x; };\n"
+ absl::string_view file = R"cc(
+ struct Defined {
+ ~Defined();
+ };
+ struct MemberImplicit {
+ Defined x;
+ };
+ struct MemberDefaulted {
+ ~MemberDefaulted() = default;
+ Defined x;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
- EXPECT_THAT(records, SizeIs(1));
+ EXPECT_THAT(records, SizeIs(3));
EXPECT_THAT(records, Each(Pointee(Destructor(DefinitionIs(
SpecialMemberFunc::Definition::kNontrivial)))));
}
TEST(AstVisitorTest, DeletedDestructor) {
- absl::string_view file = "struct Deleted { ~Deleted() = delete;};\n";
- // TODO(b/202113881): "struct DeletedByMember { Deleted x; };\n"
+ absl::string_view file = R"cc(
+ struct Deleted {
+ ~Deleted() = delete;
+ };
+ struct DeletedByMember {
+ Deleted x;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
- EXPECT_THAT(records, SizeIs(1));
+ EXPECT_THAT(records, SizeIs(2));
EXPECT_THAT(records, Each(Pointee(Destructor(DefinitionIs(
SpecialMemberFunc::Definition::kDeleted)))));
}
TEST(AstVisitorTest, PublicDestructor) {
- absl::string_view file =
- "class Implicit {};\n"
- "struct Defaulted { ~Defaulted() = default; };\n"
- "class Section { public: ~Section() = default; };\n";
+ absl::string_view file = R"cc(
+ class Implicit {};
+ struct Defaulted {
+ ~Defaulted() = default;
+ };
+ class Section {
+ public:
+ ~Section() = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
@@ -472,9 +550,15 @@
}
TEST(AstVisitorTest, PrivateDestructor) {
- absl::string_view file =
- "class Defaulted { ~Defaulted() = default; };\n"
- "struct Section { private: ~Section() = default; };\n";
+ absl::string_view file = R"cc(
+ class Defaulted {
+ ~Defaulted() = default;
+ };
+ struct Section {
+ private:
+ ~Section() = default;
+ };
+ )cc";
ASSERT_OK_AND_ASSIGN(IR ir, IrFromCc({file}));
std::vector<Record*> records = ir.get_items_if<Record>();
diff --git a/rs_bindings_from_cc/test/golden/nontrivial_type.h b/rs_bindings_from_cc/test/golden/nontrivial_type.h
index 9ce57f1..75f5f50 100644
--- a/rs_bindings_from_cc/test/golden/nontrivial_type.h
+++ b/rs_bindings_from_cc/test/golden/nontrivial_type.h
@@ -12,4 +12,6 @@
int field;
};
+void TakesByValue(Nontrivial nontrivial);
+
#endif // CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_NONTRIVIAL_TYPE_H_
diff --git a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs
index f1c94be..7ec96b2 100644
--- a/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/nontrivial_type_rs_api.rs
@@ -18,6 +18,10 @@
// Error while generating bindings for item 'Nontrivial::Nontrivial':
// Parameter type 'struct Nontrivial &&' is not supported
+// rs_bindings_from_cc/test/golden/nontrivial_type.h;l=11
+// Error while generating bindings for item 'TakesByValue':
+// Non-trivial_abi type 'struct Nontrivial' is not supported by value as a parameter
+
// CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_NONTRIVIAL_TYPE_H_
mod detail {
diff --git a/rs_bindings_from_cc/test/golden/types.h b/rs_bindings_from_cc/test/golden/types.h
index ee4f14b..784c51d 100644
--- a/rs_bindings_from_cc/test/golden/types.h
+++ b/rs_bindings_from_cc/test/golden/types.h
@@ -8,6 +8,10 @@
#include <cstddef>
#include <cstdint>
+struct SomeStruct {
+ bool not_empty; // TODO(b/202737338): delete this.
+};
+
struct FieldTypeTestStruct {
bool bool_field;
char char_field;
@@ -50,6 +54,11 @@
float float_field;
double double_field;
+
+ int* ptr_field;
+
+ SomeStruct struct_field;
+ SomeStruct* struct_ptr_field;
};
inline void VoidReturningFunction() {}
diff --git a/rs_bindings_from_cc/test/golden/types_rs_api.rs b/rs_bindings_from_cc/test/golden/types_rs_api.rs
index 859d280..5d9949f 100644
--- a/rs_bindings_from_cc/test/golden/types_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/types_rs_api.rs
@@ -9,6 +9,13 @@
#[derive(Clone, Copy)]
#[repr(C)]
+pub struct SomeStruct {
+ /// TODO(b/202737338): delete this.
+ pub not_empty: bool,
+}
+
+#[derive(Clone, Copy)]
+#[repr(C)]
pub struct FieldTypeTestStruct {
pub bool_field: bool,
pub char_field: u8,
@@ -43,6 +50,9 @@
pub uintptr_t_field: usize,
pub float_field: f32,
pub double_field: f64,
+ pub ptr_field: *mut i32,
+ pub struct_field: SomeStruct,
+ pub struct_ptr_field: *mut SomeStruct,
}
#[inline(always)]
@@ -58,7 +68,11 @@
}
}
-const_assert_eq!(std::mem::size_of::<FieldTypeTestStruct>(), 168usize);
+const_assert_eq!(std::mem::size_of::<SomeStruct>(), 1usize);
+const_assert_eq!(std::mem::align_of::<SomeStruct>(), 1usize);
+const_assert_eq!(offset_of!(SomeStruct, not_empty) * 8, 0usize);
+
+const_assert_eq!(std::mem::size_of::<FieldTypeTestStruct>(), 192usize);
const_assert_eq!(std::mem::align_of::<FieldTypeTestStruct>(), 8usize);
const_assert_eq!(offset_of!(FieldTypeTestStruct, bool_field) * 8, 0usize);
const_assert_eq!(offset_of!(FieldTypeTestStruct, char_field) * 8, 8usize);
@@ -93,3 +107,6 @@
const_assert_eq!(offset_of!(FieldTypeTestStruct, uintptr_t_field) * 8, 1152usize);
const_assert_eq!(offset_of!(FieldTypeTestStruct, float_field) * 8, 1216usize);
const_assert_eq!(offset_of!(FieldTypeTestStruct, double_field) * 8, 1280usize);
+const_assert_eq!(offset_of!(FieldTypeTestStruct, ptr_field) * 8, 1344usize);
+const_assert_eq!(offset_of!(FieldTypeTestStruct, struct_field) * 8, 1408usize);
+const_assert_eq!(offset_of!(FieldTypeTestStruct, struct_ptr_field) * 8, 1472usize);
diff --git a/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc
index b66ef7c..07c9ec9 100644
--- a/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/types_rs_api_impl.cc
@@ -9,7 +9,11 @@
return VoidReturningFunction();
}
-static_assert(sizeof(FieldTypeTestStruct) == 168);
+static_assert(sizeof(SomeStruct) == 1);
+static_assert(alignof(SomeStruct) == 1);
+static_assert(offsetof(SomeStruct, not_empty) * 8 == 0);
+
+static_assert(sizeof(FieldTypeTestStruct) == 192);
static_assert(alignof(FieldTypeTestStruct) == 8);
static_assert(offsetof(FieldTypeTestStruct, bool_field) * 8 == 0);
static_assert(offsetof(FieldTypeTestStruct, char_field) * 8 == 8);
@@ -45,3 +49,6 @@
static_assert(offsetof(FieldTypeTestStruct, uintptr_t_field) * 8 == 1152);
static_assert(offsetof(FieldTypeTestStruct, float_field) * 8 == 1216);
static_assert(offsetof(FieldTypeTestStruct, double_field) * 8 == 1280);
+static_assert(offsetof(FieldTypeTestStruct, ptr_field) * 8 == 1344);
+static_assert(offsetof(FieldTypeTestStruct, struct_field) * 8 == 1408);
+static_assert(offsetof(FieldTypeTestStruct, struct_ptr_field) * 8 == 1472);
diff --git a/rs_bindings_from_cc/test/golden/unsupported.h b/rs_bindings_from_cc/test/golden/unsupported.h
index 204bff1..dc3cb11 100644
--- a/rs_bindings_from_cc/test/golden/unsupported.h
+++ b/rs_bindings_from_cc/test/golden/unsupported.h
@@ -5,14 +5,16 @@
#ifndef CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_UNSUPPORTED_H_
#define CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_UNSUPPORTED_H_
-struct CustomType {
+struct NontrivialCustomType {
+ NontrivialCustomType(NontrivialCustomType&&);
+
int i;
};
-void UnsupportedParamType(CustomType n);
+void UnsupportedParamType(NontrivialCustomType n);
void UnsupportedUnnamedParam(int);
-CustomType UnsupportedReturnType();
+NontrivialCustomType UnsupportedReturnType();
-CustomType MultipleReasons(CustomType n, int);
+NontrivialCustomType MultipleReasons(NontrivialCustomType n, int);
#endif // CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_UNSUPPORTED_H_
diff --git a/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs b/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs
index d22dd38..978800d 100644
--- a/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/unsupported_rs_api.rs
@@ -1,4 +1,4 @@
-#![feature(const_maybe_uninit_as_ptr, const_ptr_offset_from, const_raw_ptr_deref)]
+#![feature(const_maybe_uninit_as_ptr, const_ptr_offset_from, const_raw_ptr_deref, negative_impls)]
// 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
@@ -7,38 +7,43 @@
use memoffset_unstable_const::offset_of;
use static_assertions::const_assert_eq;
-#[derive(Clone, Copy)]
#[repr(C)]
-pub struct CustomType {
+pub struct NontrivialCustomType {
pub i: i32,
}
-// rs_bindings_from_cc/test/golden/unsupported.h;l=8
-// Error while generating bindings for item 'UnsupportedParamType':
-// Parameter type 'struct CustomType' is not supported
+impl !Unpin for NontrivialCustomType {}
-// rs_bindings_from_cc/test/golden/unsupported.h;l=9
+// rs_bindings_from_cc/test/golden/unsupported.h;l=5
+// Error while generating bindings for item 'NontrivialCustomType::NontrivialCustomType':
+// Parameter type 'struct NontrivialCustomType &&' is not supported
+
+// rs_bindings_from_cc/test/golden/unsupported.h;l=10
+// Error while generating bindings for item 'UnsupportedParamType':
+// Non-trivial_abi type 'struct NontrivialCustomType' is not supported by value as a parameter
+
+// rs_bindings_from_cc/test/golden/unsupported.h;l=11
// Error while generating bindings for item 'UnsupportedUnnamedParam':
// Empty parameter names are not supported
-// rs_bindings_from_cc/test/golden/unsupported.h;l=10
+// rs_bindings_from_cc/test/golden/unsupported.h;l=12
// Error while generating bindings for item 'UnsupportedReturnType':
-// Return type 'struct CustomType' is not supported
+// Non-trivial_abi type 'struct NontrivialCustomType' is not supported by value as a return type
-// rs_bindings_from_cc/test/golden/unsupported.h;l=12
+// rs_bindings_from_cc/test/golden/unsupported.h;l=14
// Error while generating bindings for item 'MultipleReasons':
-// Parameter type 'struct CustomType' is not supported
+// Non-trivial_abi type 'struct NontrivialCustomType' is not supported by value as a parameter
-// rs_bindings_from_cc/test/golden/unsupported.h;l=12
+// rs_bindings_from_cc/test/golden/unsupported.h;l=14
// Error while generating bindings for item 'MultipleReasons':
// Empty parameter names are not supported
-// rs_bindings_from_cc/test/golden/unsupported.h;l=12
+// rs_bindings_from_cc/test/golden/unsupported.h;l=14
// Error while generating bindings for item 'MultipleReasons':
-// Return type 'struct CustomType' is not supported
+// Non-trivial_abi type 'struct NontrivialCustomType' is not supported by value as a return type
// CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_UNSUPPORTED_H_
-const_assert_eq!(std::mem::size_of::<CustomType>(), 4usize);
-const_assert_eq!(std::mem::align_of::<CustomType>(), 4usize);
-const_assert_eq!(offset_of!(CustomType, i) * 8, 0usize);
+const_assert_eq!(std::mem::size_of::<NontrivialCustomType>(), 4usize);
+const_assert_eq!(std::mem::align_of::<NontrivialCustomType>(), 4usize);
+const_assert_eq!(offset_of!(NontrivialCustomType, i) * 8, 0usize);
diff --git a/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc
index 82da54d..cc9fb1a 100644
--- a/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/unsupported_rs_api_impl.cc
@@ -5,6 +5,6 @@
#include <cstddef>
#include "rs_bindings_from_cc/test/golden/unsupported.h"
-static_assert(sizeof(CustomType) == 4);
-static_assert(alignof(CustomType) == 4);
-static_assert(offsetof(CustomType, i) * 8 == 0);
+static_assert(sizeof(NontrivialCustomType) == 4);
+static_assert(alignof(NontrivialCustomType) == 4);
+static_assert(offsetof(NontrivialCustomType, i) * 8 == 0);