Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions syntax/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ fn check_type_box(cx: &mut Check, ptr: &Ty1) {
fn check_type_rust_vec(cx: &mut Check, ty: &Ty1) {
if let Type::Ident(ident) = &ty.inner {
if cx.types.cxx.contains(&ident.rust)
&& !cx.types.aliases.contains_key(&ident.rust)
&& !cx.types.structs.contains_key(&ident.rust)
&& !cx.types.enums.contains_key(&ident.rust)
{
Expand Down Expand Up @@ -328,6 +329,7 @@ fn check_api_type(cx: &mut Check, ety: &ExternType) {
TrivialReason::StructField(strct) => format!("a field of `{}`", strct.name.rust),
TrivialReason::FunctionArgument(efn) => format!("an argument of `{}`", efn.name.rust),
TrivialReason::FunctionReturn(efn) => format!("a return value of `{}`", efn.name.rust),
TrivialReason::VecElement => format!("a vector element in Vec<{}>", ety.name.rust),
};
let msg = format!(
"needs a cxx::ExternType impl in order to be used as {}",
Expand Down
7 changes: 7 additions & 0 deletions syntax/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ impl<'a> Types<'a> {
_ => {}
}
}
for ty in &all {
if let Type::RustVec(ty) = ty {
let reason = TrivialReason::VecElement;
insist_alias_types_are_trivial(&ty.inner, reason);
}
}

let mut types = Types {
all,
Expand Down Expand Up @@ -297,6 +303,7 @@ pub enum TrivialReason<'a> {
StructField(&'a Struct),
FunctionArgument(&'a ExternFn),
FunctionReturn(&'a ExternFn),
VecElement,
}

fn duplicate_name(cx: &mut Errors, sp: impl ToTokens, ident: &Ident) {
Expand Down
1 change: 1 addition & 0 deletions tests/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ cxx_library(
],
headers = {
"ffi/lib.rs.h": ":bridge/header",
"ffi/module.rs.h": ":module/header",
"ffi/tests.h": "ffi/tests.h",
},
deps = ["//:core"],
Expand Down
1 change: 1 addition & 0 deletions tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ cc_library(
hdrs = ["ffi/tests.h"],
deps = [
":bridge/include",
":module/include",
"//:core",
],
)
Expand Down
8 changes: 8 additions & 0 deletions tests/ffi/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ pub mod ffi {
}

extern "C++" {
include!("tests/ffi/module.rs.h");

type COwnedEnum;
type Job = crate::module::ffi::Job;
}

#[repr(u32)]
Expand All @@ -211,6 +214,7 @@ pub mod ffi {
fn r_return_unique_ptr_string() -> UniquePtr<CxxString>;
fn r_return_rust_vec() -> Vec<u8>;
fn r_return_rust_vec_string() -> Vec<String>;
fn r_return_rust_vec_extern_struct() -> Vec<Job>;
fn r_return_ref_rust_vec(shared: &Shared) -> &Vec<u8>;
fn r_return_mut_rust_vec(shared: &mut Shared) -> &mut Vec<u8>;
fn r_return_identity(_: usize) -> usize;
Expand Down Expand Up @@ -435,6 +439,10 @@ fn r_return_rust_vec_string() -> Vec<String> {
Vec::new()
}

fn r_return_rust_vec_extern_struct() -> Vec<ffi::Job> {
Vec::new()
}

fn r_return_ref_rust_vec(shared: &ffi::Shared) -> &Vec<u8> {
let _ = shared;
unimplemented!()
Expand Down
4 changes: 4 additions & 0 deletions tests/ffi/module.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#[cxx::bridge(namespace = "tests")]
pub mod ffi {
struct Job {
raw: u32,
}

unsafe extern "C++" {
include!("tests/ffi/tests.h");

Expand Down
34 changes: 34 additions & 0 deletions tests/ui/vec_opaque.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#[cxx::bridge]
mod handle {
extern "C++" {
type Job;
}
}

#[cxx::bridge]
mod ffi1 {
extern "C++" {
type Job;
}

extern "Rust" {
fn f() -> Vec<Job>;
}
}

#[cxx::bridge]
mod ffi2 {
extern "C++" {
type Job = crate::handle::Job;
}

extern "Rust" {
fn f() -> Vec<Job>;
}
}

fn f() -> Vec<handle::Job> {
unimplemented!()
}

fn main() {}
22 changes: 22 additions & 0 deletions tests/ui/vec_opaque.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error: Rust Vec containing C++ type is not supported yet
--> $DIR/vec_opaque.rs:15:19
|
15 | fn f() -> Vec<Job>;
| ^^^^^^^^

error: needs a cxx::ExternType impl in order to be used as a vector element in Vec<Job>
--> $DIR/vec_opaque.rs:11:9
|
11 | type Job;
| ^^^^^^^^

error[E0271]: type mismatch resolving `<handle::Job as ExternType>::Kind == Trivial`
--> $DIR/vec_opaque.rs:22:9
|
22 | type Job = crate::handle::Job;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Trivial`, found enum `cxx::kind::Opaque`
|
::: $WORKSPACE/src/extern_type.rs
|
| pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
| ----------- required by this bound in `verify_extern_kind`