Restrict extern Rust types to unique local types for now

This commit is contained in:
David Tolnay 2020-11-17 07:54:54 -08:00
parent bf7ae81229
commit 62cae8e16c
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
7 changed files with 47 additions and 32 deletions

View File

@ -32,14 +32,14 @@ fn expand(ffi: Module, apis: &[Api], types: &Types) -> TokenStream {
for api in apis {
if let Api::RustType(ety) = api {
expanded.extend(expand_rust_type(ety));
expanded.extend(expand_rust_type_import(ety));
hidden.extend(expand_rust_type_assert_sized(ety));
}
}
for api in apis {
match api {
Api::Include(_) | Api::RustType(_) | Api::Impl(_) => {}
Api::Include(_) | Api::Impl(_) => {}
Api::Struct(strct) => expanded.extend(expand_struct(strct)),
Api::Enum(enm) => expanded.extend(expand_enum(enm)),
Api::CxxType(ety) => {
@ -52,6 +52,7 @@ fn expand(ffi: Module, apis: &[Api], types: &Types) -> TokenStream {
Api::CxxFunction(efn) => {
expanded.extend(expand_cxx_function_shim(efn, types));
}
Api::RustType(ety) => expanded.extend(expand_rust_type_impl(ety)),
Api::RustFunction(efn) => hidden.extend(expand_rust_function_shim(efn, types)),
Api::TypeAlias(alias) => {
expanded.extend(expand_type_alias(alias));
@ -490,13 +491,25 @@ fn expand_function_pointer_trampoline(
}
}
fn expand_rust_type(ety: &ExternType) -> TokenStream {
fn expand_rust_type_import(ety: &ExternType) -> TokenStream {
let ident = &ety.name.rust;
quote! {
let span = ident.span();
quote_spanned! {span=>
use super::#ident;
}
}
fn expand_rust_type_impl(ety: &ExternType) -> TokenStream {
let ident = &ety.name.rust;
let span = ident.span();
let unsafe_impl = quote_spanned!(ety.type_token.span=> unsafe impl);
quote_spanned! {span=>
#unsafe_impl ::cxx::private::RustType for #ident {}
}
}
fn expand_rust_type_assert_sized(ety: &ExternType) -> TokenStream {
// Rustc will render as follows if not sized:
//

View File

@ -392,6 +392,7 @@ mod result;
mod rust_sliceu8;
mod rust_str;
mod rust_string;
mod rust_type;
mod rust_vec;
mod symbols;
mod unique_ptr;
@ -435,6 +436,7 @@ pub mod private {
pub use crate::rust_sliceu8::RustSliceU8;
pub use crate::rust_str::RustStr;
pub use crate::rust_string::RustString;
pub use crate::rust_type::RustType;
pub use crate::rust_vec::RustVec;
pub use crate::unique_ptr::UniquePtrTarget;
pub use crate::unwind::catch_unwind;

1
src/rust_type.rs Normal file
View File

@ -0,0 +1 @@
pub unsafe trait RustType {}

View File

@ -230,7 +230,6 @@ pub mod ffi {
extern "Rust" {
type R;
type R2;
fn r_return_primitive() -> usize;
fn r_return_shared() -> Shared;
@ -272,9 +271,8 @@ pub mod ffi {
fn r_try_return_box() -> Result<Box<R>>;
fn r_fail_return_primitive() -> Result<usize>;
fn r_return_r2(n: usize) -> Box<R2>;
fn get(self: &R2) -> usize;
fn set(self: &mut R2, n: usize) -> usize;
fn get(self: &R) -> usize;
fn set(self: &mut R, n: usize) -> usize;
fn r_method_on_shared(self: &Shared) -> String;
#[cxx_name = "rAliasedFunction"]
@ -303,11 +301,10 @@ pub mod ffi {
}
}
pub type R = usize;
#[derive(PartialEq, Debug)]
pub struct R(pub usize);
pub struct R2(usize);
impl R2 {
impl R {
fn get(&self) -> usize {
self.0
}
@ -344,7 +341,7 @@ fn r_return_shared() -> ffi::Shared {
}
fn r_return_box() -> Box<R> {
Box::new(2020)
Box::new(R(2020))
}
fn r_return_unique_ptr() -> UniquePtr<ffi::C> {
@ -494,17 +491,13 @@ fn r_try_return_primitive() -> Result<usize, Error> {
}
fn r_try_return_box() -> Result<Box<R>, Error> {
Ok(Box::new(2020))
Ok(Box::new(R(2020)))
}
fn r_fail_return_primitive() -> Result<usize, Error> {
Err(Error)
}
fn r_return_r2(n: usize) -> Box<R2> {
Box::new(R2(n))
}
fn r_aliased_function(x: i32) -> String {
x.to_string()
}

View File

@ -625,12 +625,12 @@ extern "C" const char *cxx_run_test() noexcept {
ASSERT(std::strcmp(e.what(), "rust error") == 0);
}
auto r2 = r_return_r2(2020);
ASSERT(r2->get() == 2020);
ASSERT(r2->set(2021) == 2021);
ASSERT(r2->get() == 2021);
ASSERT(r2->set(2020) == 2020);
ASSERT(r2->get() == 2020);
auto r = r_return_box();
ASSERT(r->get() == 2020);
ASSERT(r->set(2021) == 2021);
ASSERT(r->get() == 2021);
ASSERT(r->set(2020) == 2020);
ASSERT(r->get() == 2020);
ASSERT(std::string(Shared{0}.r_method_on_shared()) == "2020");
ASSERT(std::string(rAliasedFunction(2020)) == "2020");

View File

@ -1,7 +1,7 @@
#![allow(clippy::assertions_on_constants, clippy::float_cmp, clippy::unit_cmp)]
use cxx_test_suite::extra::ffi2;
use cxx_test_suite::ffi;
use cxx_test_suite::{ffi, R};
use std::cell::Cell;
use std::ffi::CStr;
@ -30,7 +30,7 @@ fn test_c_return() {
assert_eq!(2020, ffi::c_return_primitive());
assert_eq!(2020, ffi::c_return_shared().z);
assert_eq!(2020, *ffi::c_return_box());
assert_eq!(2020, ffi::c_return_box().0);
ffi::c_return_unique_ptr();
ffi2::c_return_ns_unique_ptr();
assert_eq!(2020, *ffi::c_return_ref(&shared));
@ -89,7 +89,7 @@ fn test_c_try_return() {
"logic error",
ffi::c_fail_return_primitive().unwrap_err().what(),
);
assert_eq!(2020, *ffi::c_try_return_box().unwrap());
assert_eq!(2020, ffi::c_try_return_box().unwrap().0);
assert_eq!("2020", *ffi::c_try_return_ref(&"2020".to_owned()).unwrap());
assert_eq!("2020", ffi::c_try_return_str("2020").unwrap());
assert_eq!(b"2020", ffi::c_try_return_sliceu8(b"2020").unwrap());
@ -107,7 +107,7 @@ fn test_c_take() {
check!(ffi::c_take_ns_shared(ffi::AShared { z: 2020 }));
check!(ffi::ns_c_take_ns_shared(ffi::AShared { z: 2020 }));
check!(ffi::c_take_nested_ns_shared(ffi::ABShared { z: 2020 }));
check!(ffi::c_take_box(Box::new(2020)));
check!(ffi::c_take_box(Box::new(R(2020))));
check!(ffi::c_take_ref_c(&unique_ptr));
check!(ffi2::c_take_ref_ns_c(&unique_ptr_ns));
check!(cxx_test_suite::module::ffi::c_take_unique_ptr(unique_ptr));
@ -215,13 +215,13 @@ fn test_enum_representations() {
}
#[no_mangle]
extern "C" fn cxx_test_suite_get_box() -> *mut cxx_test_suite::R {
Box::into_raw(Box::new(2020usize))
extern "C" fn cxx_test_suite_get_box() -> *mut R {
Box::into_raw(Box::new(R(2020usize)))
}
#[no_mangle]
unsafe extern "C" fn cxx_test_suite_r_is_correct(r: *const cxx_test_suite::R) -> bool {
*r == 2020
unsafe extern "C" fn cxx_test_suite_r_is_correct(r: *const R) -> bool {
(*r).0 == 2020
}
#[test]

View File

@ -1,3 +1,9 @@
error[E0726]: implicit elided lifetime not allowed here
--> $DIR/unsupported_elided.rs:6:14
|
6 | type T;
| ^- help: indicate the anonymous lifetime: `<'_>`
error[E0106]: missing lifetime specifier
--> $DIR/unsupported_elided.rs:8:24
|