Skip to content

Commit 8ab4ecc

Browse files
committed
Add support for Vec<Box<T>>.
1 parent 6e061fe commit 8ab4ecc

File tree

6 files changed

+39
-5
lines changed

6 files changed

+39
-5
lines changed

macro/src/generics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub(crate) fn get_impl_and_ty_generics<'a>(
5858
fn get_generic_lifetimes<'a>(ty: &'a Type) -> &'a Lifetimes {
5959
match ty {
6060
Type::Ident(named_type) => &named_type.generics,
61-
Type::CxxVector(ty1) => get_generic_lifetimes(&ty1.inner),
61+
Type::RustBox(ty1) | Type::CxxVector(ty1) => get_generic_lifetimes(&ty1.inner),
6262
_ => unreachable!("syntax/check.rs should reject other types"),
6363
}
6464
}
@@ -78,7 +78,7 @@ fn get_generic_lifetimes<'a>(ty: &'a Type) -> &'a Lifetimes {
7878
fn resolve_generic_lifetimes<'a>(ty: &'a Type, types: &'a Types) -> &'a Lifetimes {
7979
match ty {
8080
Type::Ident(named_type) => types.resolve(&named_type.rust).generics,
81-
Type::CxxVector(ty1) => resolve_generic_lifetimes(&ty1.inner, types),
81+
Type::RustBox(ty1) | Type::CxxVector(ty1) => resolve_generic_lifetimes(&ty1.inner, types),
8282
_ => unreachable!("syntax/check.rs should reject other types"),
8383
}
8484
}

macro/src/tests.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,27 @@ fn test_vec_string() {
8484
assert!(rs.contains("v: &::cxx::private::RustVec<::cxx::alloc::string::String>"));
8585
assert!(rs.contains("fn __foo(v: &::cxx::alloc::vec::Vec<::cxx::alloc::string::String>)"));
8686
}
87+
88+
/// This test covers implicit impl of `Vec<Box<T>>`.
89+
#[test]
90+
fn test_vec_of_box() {
91+
let rs = bridge(quote! {
92+
mod ffi {
93+
extern "Rust" {
94+
type R;
95+
fn foo() -> Vec<Box<R>>;
96+
}
97+
}
98+
})
99+
.unwrap();
100+
assert!(rs.contains("unsafe impl ::cxx::private::ImplBox for R {}"));
101+
assert!(rs.contains("export_name = \"cxxbridge1$box$R$drop\""));
102+
103+
assert!(rs.contains("unsafe impl ::cxx::private::ImplVec for ::cxx::alloc::boxed::Box<R> {}"),);
104+
assert!(rs.contains("export_name = \"cxxbridge1$rust_vec$box$R$set_len\""));
105+
106+
// Covering these lines, because an early WIP incorrectly said`RustVec<*mut R>`
107+
// instead of `RustVec<Box<R>>` in *some* of these lines.
108+
assert!(rs.contains("__return: *mut ::cxx::private::RustVec<::cxx::alloc::boxed::Box<R>>"));
109+
assert!(rs.contains("fn __foo() -> ::cxx::alloc::vec::Vec<::cxx::alloc::boxed::Box<R>>"));
110+
}

syntax/check.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ fn check_type_rust_vec(cx: &mut Check, ty: &Ty1) {
133133
}
134134
}
135135
Type::Str(_) => return,
136+
Type::RustBox(ty1) => {
137+
check_type_box(cx, ty1);
138+
return;
139+
}
136140
_ => {}
137141
}
138142

syntax/types.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,10 @@ impl<'a> Types<'a> {
358358
Type::Ident(ident) => {
359359
Atom::from(&ident.rust).is_none() && !self.aliases.contains_key(&ident.rust)
360360
}
361-
Type::RustBox(_) => {
362-
// TODO: We should treat Box<LocalType> as local to match
361+
Type::RustBox(ty1) => {
362+
// Treating Box<LocalType> as local to match
363363
// https://doc.rust-lang.org/reference/items/implementations.html#r-items.impl.trait.fundamental
364-
false
364+
self.is_local(&ty1.inner)
365365
}
366366
Type::Array(_)
367367
| Type::CxxVector(_)

tests/ffi/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ pub mod ffi {
306306
fn r_return_rust_vec() -> Vec<u8>;
307307
fn r_return_rust_vec_string() -> Vec<String>;
308308
fn r_return_rust_vec_extern_struct() -> Vec<Job>;
309+
fn r_return_rust_vec_box() -> Vec<Box<R>>;
309310
fn r_return_ref_rust_vec(shared: &Shared) -> &Vec<u8>;
310311
fn r_return_mut_rust_vec(shared: &mut Shared) -> &mut Vec<u8>;
311312
fn r_return_identity(_: usize) -> usize;
@@ -587,6 +588,10 @@ fn r_return_rust_vec_extern_struct() -> Vec<ffi::Job> {
587588
Vec::new()
588589
}
589590

591+
fn r_return_rust_vec_box() -> Vec<Box<R>> {
592+
vec![Box::new(R(2020))]
593+
}
594+
590595
fn r_return_ref_rust_vec(shared: &ffi::Shared) -> &Vec<u8> {
591596
let _ = shared;
592597
unimplemented!()

tests/ffi/tests.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@ extern "C" const char *cxx_run_test() noexcept {
812812
ASSERT(r_return_enum(2021) == Enum::CVal);
813813
ASSERT(Shared::r_static_method_on_shared() == 2023);
814814
ASSERT(R::r_static_method() == 2024);
815+
ASSERT(r_return_rust_vec_box()[0]->get() == 2020);
815816

816817
r_take_primitive(2020);
817818
r_take_shared(Shared{2020});

0 commit comments

Comments
 (0)