Skip to content

Commit 8b37625

Browse files
thunderseethecopybara-github
authored andcommitted
Use nested bridging when parse specialization fails.
Previously, we would always unwrap an error out of `parse_rs_std_template_specialization`. For types like `Option<Proto>` this would lead to failing to format the type because specialization would try to format it in location `Other` when we need to format it as `NestedBridgeable`. We fix this by only unwrapping our error when our location doesn't admit bridging. PiperOrigin-RevId: 896082192
1 parent 4a90d11 commit 8b37625

4 files changed

Lines changed: 34 additions & 7 deletions

File tree

cc_bindings_from_rs/generate_bindings/format_type.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,15 @@ pub fn format_ty_for_cc<'tcx>(
292292

293293
let specialization = db.parse_rs_std_template_specialization(ty);
294294
if specialization.as_ref().is_some_and(|specialization| {
295-
specialization.is_err()
296-
|| specialization.as_ref().is_ok_and(|rs_std_enum| {
297-
(matches!(rs_std_enum.kind, TemplateSpecializationKind::Option { .. })
298-
&& !location.is_bridgeable())
299-
|| matches!(rs_std_enum.kind, TemplateSpecializationKind::Result { .. })
300-
})
295+
// We only want to consider errors when bridging could not occur.
296+
// Otherwise, fallthrough to the normal bridging logic.
297+
let error_occurred = !location.is_bridgeable() && specialization.is_err();
298+
let is_option_or_result = specialization.as_ref().is_ok_and(|rs_std_enum| {
299+
!location.is_bridgeable()
300+
&& matches!(rs_std_enum.kind, TemplateSpecializationKind::Option { .. })
301+
|| matches!(rs_std_enum.kind, TemplateSpecializationKind::Result { .. })
302+
});
303+
error_occurred || is_option_or_result
301304
}) {
302305
let rs_std_enum = specialization.unwrap()?;
303306
let tokens = rs_std_enum.core.self_ty_cc.clone().into_tokens(&mut prereqs);

cc_bindings_from_rs/generate_bindings/generate_struct_and_union_test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ fn test_format_bridged_type_in_generic_types() {
8989
let err = result.unwrap_err();
9090
assert_eq!(
9191
err,
92-
"Error handling parameter #0 of type `std::option::Option<std::boxed::Box<std::result::Result<RustType, ()>>>`: Generic types are not supported yet (b/259749095)"
92+
"Error handling parameter #0 of type `std::option::Option<std::boxed::Box<std::result::Result<RustType, ()>>>`: \
93+
Failed to construct CrubitAbiType for std::boxed::Box<std::result::Result<RustType, ()>> because it does not have a move ctor or assignment operator."
9394
);
9495
});
9596
}

cc_bindings_from_rs/test/enums/option.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,12 @@ pub struct OptionWithSizeTypes {
171171
pub uval: Option<usize>,
172172
pub ival: Option<isize>,
173173
}
174+
175+
#[doc = "CRUBIT_ANNOTATE: cpp_type=int"]
176+
#[doc = "CRUBIT_ANNOTATE: include_path=unused_include.h"]
177+
#[repr(transparent)]
178+
pub struct BridgedType(i32);
179+
180+
pub fn take_option_bridged(x: Option<BridgedType>) -> i32 {
181+
x.map(|b| b.0).unwrap_or(-1)
182+
}

cc_bindings_from_rs/test/enums/option_cc_api.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232

3333
namespace option {
3434
struct HasOptions;
35+
36+
// Error generating bindings for `option_golden::BridgedType` defined at
37+
// cc_bindings_from_rs/test/enums/option.rs;l=178:
38+
// Type bindings for option_golden::BridgedType suppressed due to being mapped
39+
// to an existing C++ type (int)
40+
3541
// Generated from:
3642
// cc_bindings_from_rs/test/enums/option.rs;l=120
3743
struct CRUBIT_INTERNAL_RUST_TYPE(":: option_golden :: CloneNoDefault") alignas(
@@ -297,6 +303,14 @@ OptionWithSizeTypes final {
297303
// cc_bindings_from_rs/test/enums/option.rs;l=158:
298304
// Zero-sized types (ZSTs) are not supported (b/258259459)
299305

306+
// Error generating bindings for `option_golden::take_option_bridged` defined at
307+
// cc_bindings_from_rs/test/enums/option.rs;l=180:
308+
// Error handling parameter #0 of type
309+
// `std::option::Option<option_golden::BridgedType>`: Failed to format type for
310+
// the definition of `option_golden::BridgedType`: Error formatting the
311+
// fully-qualified C++ name of `BridgedType`: `int` is a C++ reserved keyword
312+
// and can't be used as a C++ identifier
313+
300314
} // namespace option
301315

302316
#ifndef _CRUBIT_BINDINGS_FOR_rs_ustd_x00000020_x0000003a_x0000003a_x00000020Option_x00000020_x0000003c_x00000020_x0000003a_x0000003a_x00000020option_x00000020_x0000003a_x0000003a_x00000020CloneNoDefault_x00000020_x0000003e

0 commit comments

Comments
 (0)