1 #![forbid(unsafe_op_in_unsafe_fn)]
2 #![allow(
3     clippy::boxed_local,
4     clippy::derive_partial_eq_without_eq,
5     clippy::just_underscores_and_digits,
6     clippy::missing_errors_doc,
7     clippy::missing_safety_doc,
8     clippy::must_use_candidate,
9     clippy::needless_lifetimes,
10     clippy::needless_pass_by_ref_mut,
11     clippy::needless_pass_by_value,
12     clippy::ptr_arg,
13     clippy::trivially_copy_pass_by_ref,
14     clippy::unnecessary_wraps,
15     clippy::unused_self
16 )]
17 
18 pub mod cast;
19 pub mod module;
20 
21 use cxx::{type_id, CxxString, CxxVector, ExternType, SharedPtr, UniquePtr};
22 use std::fmt::{self, Display};
23 use std::mem::MaybeUninit;
24 use std::os::raw::c_char;
25 
26 #[cxx::bridge(namespace = "tests")]
27 pub mod ffi {
28     #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
29     struct Shared {
30         z: usize,
31     }
32 
33     #[derive(PartialEq, PartialOrd)]
34     struct SharedString {
35         msg: String,
36     }
37 
38     #[derive(Debug, Hash, PartialOrd, Ord)]
39     enum Enum {
40         AVal,
41         BVal = 2020,
42         #[cxx_name = "CVal"]
43         LastVal,
44     }
45 
46     #[namespace = "A"]
47     #[derive(Copy, Clone, Default)]
48     struct AShared {
49         #[cxx_name = "type"]
50         z: usize,
51     }
52 
53     #[namespace = "A"]
54     enum AEnum {
55         AAVal,
56         ABVal = 2020,
57         ACVal,
58     }
59 
60     #[namespace = "A::B"]
61     enum ABEnum {
62         ABAVal,
63         ABBVal = 2020,
64         ABCVal,
65     }
66 
67     #[namespace = "A::B"]
68     #[derive(Clone)]
69     struct ABShared {
70         z: usize,
71     }
72 
73     #[namespace = "first"]
74     struct First {
75         second: Box<Second>,
76     }
77 
78     #[namespace = "second"]
79     #[derive(Hash)]
80     struct Second {
81         i: i32,
82         e: COwnedEnum,
83     }
84 
85     pub struct Array {
86         a: [i32; 4],
87         b: Buffer,
88     }
89 
90     #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
91     pub struct StructWithLifetime<'a> {
92         s: &'a str,
93     }
94 
95     unsafe extern "C++" {
96         include!("tests/ffi/tests.h");
97 
98         type C;
99 
c_return_primitive() -> usize100         fn c_return_primitive() -> usize;
c_return_shared() -> Shared101         fn c_return_shared() -> Shared;
c_return_box() -> Box<R>102         fn c_return_box() -> Box<R>;
c_return_unique_ptr() -> UniquePtr<C>103         fn c_return_unique_ptr() -> UniquePtr<C>;
c_return_shared_ptr() -> SharedPtr<C>104         fn c_return_shared_ptr() -> SharedPtr<C>;
c_return_ref(shared: &Shared) -> &usize105         fn c_return_ref(shared: &Shared) -> &usize;
c_return_mut(shared: &mut Shared) -> &mut usize106         fn c_return_mut(shared: &mut Shared) -> &mut usize;
c_return_str(shared: &Shared) -> &str107         fn c_return_str(shared: &Shared) -> &str;
c_return_slice_char(shared: &Shared) -> &[c_char]108         fn c_return_slice_char(shared: &Shared) -> &[c_char];
c_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8]109         fn c_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8];
c_return_rust_string() -> String110         fn c_return_rust_string() -> String;
c_return_rust_string_lossy() -> String111         fn c_return_rust_string_lossy() -> String;
c_return_unique_ptr_string() -> UniquePtr<CxxString>112         fn c_return_unique_ptr_string() -> UniquePtr<CxxString>;
c_return_unique_ptr_vector_u8() -> UniquePtr<CxxVector<u8>>113         fn c_return_unique_ptr_vector_u8() -> UniquePtr<CxxVector<u8>>;
c_return_unique_ptr_vector_f64() -> UniquePtr<CxxVector<f64>>114         fn c_return_unique_ptr_vector_f64() -> UniquePtr<CxxVector<f64>>;
c_return_unique_ptr_vector_string() -> UniquePtr<CxxVector<CxxString>>115         fn c_return_unique_ptr_vector_string() -> UniquePtr<CxxVector<CxxString>>;
c_return_unique_ptr_vector_shared() -> UniquePtr<CxxVector<Shared>>116         fn c_return_unique_ptr_vector_shared() -> UniquePtr<CxxVector<Shared>>;
c_return_unique_ptr_vector_opaque() -> UniquePtr<CxxVector<C>>117         fn c_return_unique_ptr_vector_opaque() -> UniquePtr<CxxVector<C>>;
c_return_ref_vector(c: &C) -> &CxxVector<u8>118         fn c_return_ref_vector(c: &C) -> &CxxVector<u8>;
c_return_mut_vector(c: Pin<&mut C>) -> Pin<&mut CxxVector<u8>>119         fn c_return_mut_vector(c: Pin<&mut C>) -> Pin<&mut CxxVector<u8>>;
c_return_rust_vec_u8() -> Vec<u8>120         fn c_return_rust_vec_u8() -> Vec<u8>;
c_return_ref_rust_vec(c: &C) -> &Vec<u8>121         fn c_return_ref_rust_vec(c: &C) -> &Vec<u8>;
c_return_mut_rust_vec(c: Pin<&mut C>) -> &mut Vec<u8>122         fn c_return_mut_rust_vec(c: Pin<&mut C>) -> &mut Vec<u8>;
c_return_rust_vec_string() -> Vec<String>123         fn c_return_rust_vec_string() -> Vec<String>;
c_return_rust_vec_bool() -> Vec<bool>124         fn c_return_rust_vec_bool() -> Vec<bool>;
c_return_identity(_: usize) -> usize125         fn c_return_identity(_: usize) -> usize;
c_return_sum(_: usize, _: usize) -> usize126         fn c_return_sum(_: usize, _: usize) -> usize;
c_return_enum(n: u16) -> Enum127         fn c_return_enum(n: u16) -> Enum;
c_return_ns_ref(shared: &AShared) -> &usize128         fn c_return_ns_ref(shared: &AShared) -> &usize;
c_return_nested_ns_ref(shared: &ABShared) -> &usize129         fn c_return_nested_ns_ref(shared: &ABShared) -> &usize;
c_return_ns_enum(n: u16) -> AEnum130         fn c_return_ns_enum(n: u16) -> AEnum;
c_return_nested_ns_enum(n: u16) -> ABEnum131         fn c_return_nested_ns_enum(n: u16) -> ABEnum;
c_return_const_ptr(n: usize) -> *const C132         fn c_return_const_ptr(n: usize) -> *const C;
c_return_mut_ptr(n: usize) -> *mut C133         fn c_return_mut_ptr(n: usize) -> *mut C;
134 
c_take_primitive(n: usize)135         fn c_take_primitive(n: usize);
c_take_shared(shared: Shared)136         fn c_take_shared(shared: Shared);
c_take_box(r: Box<R>)137         fn c_take_box(r: Box<R>);
c_take_ref_r(r: &R)138         fn c_take_ref_r(r: &R);
c_take_ref_c(c: &C)139         fn c_take_ref_c(c: &C);
c_take_str(s: &str)140         fn c_take_str(s: &str);
c_take_slice_char(s: &[c_char])141         fn c_take_slice_char(s: &[c_char]);
c_take_slice_shared(s: &[Shared])142         fn c_take_slice_shared(s: &[Shared]);
c_take_slice_shared_sort(s: &mut [Shared])143         fn c_take_slice_shared_sort(s: &mut [Shared]);
c_take_slice_r(s: &[R])144         fn c_take_slice_r(s: &[R]);
c_take_slice_r_sort(s: &mut [R])145         fn c_take_slice_r_sort(s: &mut [R]);
c_take_rust_string(s: String)146         fn c_take_rust_string(s: String);
c_take_unique_ptr_string(s: UniquePtr<CxxString>)147         fn c_take_unique_ptr_string(s: UniquePtr<CxxString>);
c_take_unique_ptr_vector_u8(v: UniquePtr<CxxVector<u8>>)148         fn c_take_unique_ptr_vector_u8(v: UniquePtr<CxxVector<u8>>);
c_take_unique_ptr_vector_f64(v: UniquePtr<CxxVector<f64>>)149         fn c_take_unique_ptr_vector_f64(v: UniquePtr<CxxVector<f64>>);
c_take_unique_ptr_vector_string(v: UniquePtr<CxxVector<CxxString>>)150         fn c_take_unique_ptr_vector_string(v: UniquePtr<CxxVector<CxxString>>);
c_take_unique_ptr_vector_shared(v: UniquePtr<CxxVector<Shared>>)151         fn c_take_unique_ptr_vector_shared(v: UniquePtr<CxxVector<Shared>>);
c_take_ref_vector(v: &CxxVector<u8>)152         fn c_take_ref_vector(v: &CxxVector<u8>);
c_take_rust_vec(v: Vec<u8>)153         fn c_take_rust_vec(v: Vec<u8>);
c_take_rust_vec_shared(v: Vec<Shared>)154         fn c_take_rust_vec_shared(v: Vec<Shared>);
c_take_rust_vec_string(v: Vec<String>)155         fn c_take_rust_vec_string(v: Vec<String>);
c_take_rust_vec_index(v: Vec<u8>)156         fn c_take_rust_vec_index(v: Vec<u8>);
c_take_rust_vec_shared_index(v: Vec<Shared>)157         fn c_take_rust_vec_shared_index(v: Vec<Shared>);
c_take_rust_vec_shared_push(v: Vec<Shared>)158         fn c_take_rust_vec_shared_push(v: Vec<Shared>);
c_take_rust_vec_shared_truncate(v: Vec<Shared>)159         fn c_take_rust_vec_shared_truncate(v: Vec<Shared>);
c_take_rust_vec_shared_clear(v: Vec<Shared>)160         fn c_take_rust_vec_shared_clear(v: Vec<Shared>);
c_take_rust_vec_shared_forward_iterator(v: Vec<Shared>)161         fn c_take_rust_vec_shared_forward_iterator(v: Vec<Shared>);
c_take_rust_vec_shared_sort(v: Vec<Shared>)162         fn c_take_rust_vec_shared_sort(v: Vec<Shared>);
c_take_ref_rust_vec(v: &Vec<u8>)163         fn c_take_ref_rust_vec(v: &Vec<u8>);
c_take_ref_rust_vec_string(v: &Vec<String>)164         fn c_take_ref_rust_vec_string(v: &Vec<String>);
c_take_ref_rust_vec_index(v: &Vec<u8>)165         fn c_take_ref_rust_vec_index(v: &Vec<u8>);
c_take_ref_rust_vec_copy(v: &Vec<u8>)166         fn c_take_ref_rust_vec_copy(v: &Vec<u8>);
c_take_ref_shared_string(s: &SharedString) -> &SharedString167         fn c_take_ref_shared_string(s: &SharedString) -> &SharedString;
c_take_callback(callback: fn(String) -> usize)168         fn c_take_callback(callback: fn(String) -> usize);
c_take_callback_ref(callback: fn(&String))169         fn c_take_callback_ref(callback: fn(&String));
170         #[cxx_name = "c_take_callback_ref"]
c_take_callback_ref_lifetime<'a>(callback: fn(&'a String))171         fn c_take_callback_ref_lifetime<'a>(callback: fn(&'a String));
c_take_callback_mut(callback: fn(&mut String))172         fn c_take_callback_mut(callback: fn(&mut String));
c_take_enum(e: Enum)173         fn c_take_enum(e: Enum);
c_take_ns_enum(e: AEnum)174         fn c_take_ns_enum(e: AEnum);
c_take_nested_ns_enum(e: ABEnum)175         fn c_take_nested_ns_enum(e: ABEnum);
c_take_ns_shared(shared: AShared)176         fn c_take_ns_shared(shared: AShared);
c_take_nested_ns_shared(shared: ABShared)177         fn c_take_nested_ns_shared(shared: ABShared);
c_take_rust_vec_ns_shared(v: Vec<AShared>)178         fn c_take_rust_vec_ns_shared(v: Vec<AShared>);
c_take_rust_vec_nested_ns_shared(v: Vec<ABShared>)179         fn c_take_rust_vec_nested_ns_shared(v: Vec<ABShared>);
c_take_const_ptr(c: *const C) -> usize180         unsafe fn c_take_const_ptr(c: *const C) -> usize;
c_take_mut_ptr(c: *mut C) -> usize181         unsafe fn c_take_mut_ptr(c: *mut C) -> usize;
182 
c_try_return_void() -> Result<()>183         fn c_try_return_void() -> Result<()>;
c_try_return_primitive() -> Result<usize>184         fn c_try_return_primitive() -> Result<usize>;
c_fail_return_primitive() -> Result<usize>185         fn c_fail_return_primitive() -> Result<usize>;
c_try_return_box() -> Result<Box<R>>186         fn c_try_return_box() -> Result<Box<R>>;
c_try_return_ref(s: &String) -> Result<&String>187         fn c_try_return_ref(s: &String) -> Result<&String>;
c_try_return_str(s: &str) -> Result<&str>188         fn c_try_return_str(s: &str) -> Result<&str>;
c_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>189         fn c_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>;
c_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>190         fn c_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>;
c_try_return_rust_string() -> Result<String>191         fn c_try_return_rust_string() -> Result<String>;
c_try_return_unique_ptr_string() -> Result<UniquePtr<CxxString>>192         fn c_try_return_unique_ptr_string() -> Result<UniquePtr<CxxString>>;
c_try_return_rust_vec() -> Result<Vec<u8>>193         fn c_try_return_rust_vec() -> Result<Vec<u8>>;
c_try_return_rust_vec_string() -> Result<Vec<String>>194         fn c_try_return_rust_vec_string() -> Result<Vec<String>>;
c_try_return_ref_rust_vec(c: &C) -> Result<&Vec<u8>>195         fn c_try_return_ref_rust_vec(c: &C) -> Result<&Vec<u8>>;
196 
get(self: &C) -> usize197         fn get(self: &C) -> usize;
set(self: Pin<&mut C>, n: usize) -> usize198         fn set(self: Pin<&mut C>, n: usize) -> usize;
get2(&self) -> usize199         fn get2(&self) -> usize;
getRef(self: &C) -> &usize200         fn getRef(self: &C) -> &usize;
getMut(self: Pin<&mut C>) -> &mut usize201         fn getMut(self: Pin<&mut C>) -> &mut usize;
set_succeed(self: Pin<&mut C>, n: usize) -> Result<usize>202         fn set_succeed(self: Pin<&mut C>, n: usize) -> Result<usize>;
get_fail(self: Pin<&mut C>) -> Result<usize>203         fn get_fail(self: Pin<&mut C>) -> Result<usize>;
c_method_on_shared(self: &Shared) -> usize204         fn c_method_on_shared(self: &Shared) -> usize;
c_method_ref_on_shared(self: &Shared) -> &usize205         fn c_method_ref_on_shared(self: &Shared) -> &usize;
c_method_mut_on_shared(self: &mut Shared) -> &mut usize206         fn c_method_mut_on_shared(self: &mut Shared) -> &mut usize;
c_set_array(self: &mut Array, value: i32)207         fn c_set_array(self: &mut Array, value: i32);
208 
c_get_use_count(weak: &WeakPtr<C>) -> usize209         fn c_get_use_count(weak: &WeakPtr<C>) -> usize;
210 
211         #[rust_name = "i32_overloaded_method"]
cOverloadedMethod(&self, x: i32) -> String212         fn cOverloadedMethod(&self, x: i32) -> String;
213         #[rust_name = "str_overloaded_method"]
cOverloadedMethod(&self, x: &str) -> String214         fn cOverloadedMethod(&self, x: &str) -> String;
215         #[rust_name = "i32_overloaded_function"]
cOverloadedFunction(x: i32) -> String216         fn cOverloadedFunction(x: i32) -> String;
217         #[rust_name = "str_overloaded_function"]
cOverloadedFunction(x: &str) -> String218         fn cOverloadedFunction(x: &str) -> String;
219 
220         #[namespace = "other"]
ns_c_take_ns_shared(shared: AShared)221         fn ns_c_take_ns_shared(shared: AShared);
222     }
223 
224     extern "C++" {
225         include!("tests/ffi/module.rs.h");
226 
227         type COwnedEnum;
228         type Job = crate::module::ffi::Job;
229     }
230 
231     extern "Rust" {
232         #[derive(ExternType)]
233         type Reference<'a>;
234     }
235 
236     unsafe extern "C++" {
237         type Borrow<'a>;
238 
c_return_borrow<'a>(s: &'a CxxString) -> UniquePtr<Borrow<'a>>239         fn c_return_borrow<'a>(s: &'a CxxString) -> UniquePtr<Borrow<'a>>;
240 
241         #[rust_name = "c_return_borrow_elided"]
c_return_borrow(s: &CxxString) -> UniquePtr<Borrow>242         fn c_return_borrow(s: &CxxString) -> UniquePtr<Borrow>;
243 
const_member(self: &Borrow)244         fn const_member(self: &Borrow);
nonconst_member(self: Pin<&mut Borrow>)245         fn nonconst_member(self: Pin<&mut Borrow>);
246     }
247 
248     #[repr(u32)]
249     #[derive(Hash)]
250     enum COwnedEnum {
251         #[cxx_name = "CVAL1"]
252         CVal1,
253         #[cxx_name = "CVAL2"]
254         CVal2,
255     }
256 
257     extern "C++" {
258         type Buffer = crate::Buffer;
259     }
260 
261     extern "Rust" {
262         type R;
263 
r_return_primitive() -> usize264         fn r_return_primitive() -> usize;
r_return_shared() -> Shared265         fn r_return_shared() -> Shared;
r_return_box() -> Box<R>266         fn r_return_box() -> Box<R>;
r_return_unique_ptr() -> UniquePtr<C>267         fn r_return_unique_ptr() -> UniquePtr<C>;
r_return_shared_ptr() -> SharedPtr<C>268         fn r_return_shared_ptr() -> SharedPtr<C>;
r_return_ref(shared: &Shared) -> &usize269         fn r_return_ref(shared: &Shared) -> &usize;
r_return_mut(shared: &mut Shared) -> &mut usize270         fn r_return_mut(shared: &mut Shared) -> &mut usize;
r_return_str(shared: &Shared) -> &str271         fn r_return_str(shared: &Shared) -> &str;
r_return_sliceu8(shared: &Shared) -> &[u8]272         fn r_return_sliceu8(shared: &Shared) -> &[u8];
r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8]273         fn r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8];
r_return_rust_string() -> String274         fn r_return_rust_string() -> String;
r_return_unique_ptr_string() -> UniquePtr<CxxString>275         fn r_return_unique_ptr_string() -> UniquePtr<CxxString>;
r_return_rust_vec() -> Vec<u8>276         fn r_return_rust_vec() -> Vec<u8>;
r_return_rust_vec_string() -> Vec<String>277         fn r_return_rust_vec_string() -> Vec<String>;
r_return_rust_vec_extern_struct() -> Vec<Job>278         fn r_return_rust_vec_extern_struct() -> Vec<Job>;
r_return_ref_rust_vec(shared: &Shared) -> &Vec<u8>279         fn r_return_ref_rust_vec(shared: &Shared) -> &Vec<u8>;
r_return_mut_rust_vec(shared: &mut Shared) -> &mut Vec<u8>280         fn r_return_mut_rust_vec(shared: &mut Shared) -> &mut Vec<u8>;
r_return_identity(_: usize) -> usize281         fn r_return_identity(_: usize) -> usize;
r_return_sum(_: usize, _: usize) -> usize282         fn r_return_sum(_: usize, _: usize) -> usize;
r_return_enum(n: u32) -> Enum283         fn r_return_enum(n: u32) -> Enum;
284 
r_take_primitive(n: usize)285         fn r_take_primitive(n: usize);
r_take_shared(shared: Shared)286         fn r_take_shared(shared: Shared);
r_take_box(r: Box<R>)287         fn r_take_box(r: Box<R>);
r_take_unique_ptr(c: UniquePtr<C>)288         fn r_take_unique_ptr(c: UniquePtr<C>);
r_take_shared_ptr(c: SharedPtr<C>)289         fn r_take_shared_ptr(c: SharedPtr<C>);
r_take_ref_r(r: &R)290         fn r_take_ref_r(r: &R);
r_take_ref_c(c: &C)291         fn r_take_ref_c(c: &C);
r_take_str(s: &str)292         fn r_take_str(s: &str);
r_take_slice_char(s: &[c_char])293         fn r_take_slice_char(s: &[c_char]);
r_take_rust_string(s: String)294         fn r_take_rust_string(s: String);
r_take_unique_ptr_string(s: UniquePtr<CxxString>)295         fn r_take_unique_ptr_string(s: UniquePtr<CxxString>);
r_take_ref_vector(v: &CxxVector<u8>)296         fn r_take_ref_vector(v: &CxxVector<u8>);
r_take_ref_empty_vector(v: &CxxVector<u64>)297         fn r_take_ref_empty_vector(v: &CxxVector<u64>);
r_take_rust_vec(v: Vec<u8>)298         fn r_take_rust_vec(v: Vec<u8>);
r_take_rust_vec_string(v: Vec<String>)299         fn r_take_rust_vec_string(v: Vec<String>);
r_take_ref_rust_vec(v: &Vec<u8>)300         fn r_take_ref_rust_vec(v: &Vec<u8>);
r_take_ref_rust_vec_string(v: &Vec<String>)301         fn r_take_ref_rust_vec_string(v: &Vec<String>);
r_take_enum(e: Enum)302         fn r_take_enum(e: Enum);
303 
r_try_return_void() -> Result<()>304         fn r_try_return_void() -> Result<()>;
r_try_return_primitive() -> Result<usize>305         fn r_try_return_primitive() -> Result<usize>;
r_try_return_box() -> Result<Box<R>>306         fn r_try_return_box() -> Result<Box<R>>;
r_fail_return_primitive() -> Result<usize>307         fn r_fail_return_primitive() -> Result<usize>;
r_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>308         fn r_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>;
r_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>309         fn r_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>;
310 
get(self: &R) -> usize311         fn get(self: &R) -> usize;
set(self: &mut R, n: usize) -> usize312         fn set(self: &mut R, n: usize) -> usize;
r_method_on_shared(self: &Shared) -> String313         fn r_method_on_shared(self: &Shared) -> String;
r_get_array_sum(self: &Array) -> i32314         fn r_get_array_sum(self: &Array) -> i32;
315 
316         #[cxx_name = "rAliasedFunction"]
r_aliased_function(x: i32) -> String317         fn r_aliased_function(x: i32) -> String;
318     }
319 
320     struct Dag0 {
321         i: i32,
322     }
323 
324     struct Dag1 {
325         dag2: Dag2,
326         vec: Vec<Dag3>,
327     }
328 
329     struct Dag2 {
330         dag4: Dag4,
331     }
332 
333     struct Dag3 {
334         dag1: Dag1,
335     }
336 
337     struct Dag4 {
338         dag0: Dag0,
339     }
340 
341     impl Box<Shared> {}
342     impl CxxVector<SharedString> {}
343 }
344 
345 mod other {
346     use cxx::kind::{Opaque, Trivial};
347     use cxx::{type_id, CxxString, ExternType};
348 
349     #[repr(C)]
350     pub struct D {
351         pub d: u64,
352     }
353 
354     #[repr(C)]
355     pub struct E {
356         e: u64,
357         e_str: CxxString,
358     }
359 
360     pub mod f {
361         use cxx::kind::Opaque;
362         use cxx::{type_id, CxxString, ExternType};
363 
364         #[repr(C)]
365         pub struct F {
366             e: u64,
367             e_str: CxxString,
368         }
369 
370         unsafe impl ExternType for F {
371             type Id = type_id!("F::F");
372             type Kind = Opaque;
373         }
374     }
375 
376     #[repr(C)]
377     pub struct G {
378         pub g: u64,
379     }
380 
381     unsafe impl ExternType for G {
382         type Id = type_id!("G::G");
383         type Kind = Trivial;
384     }
385 
386     unsafe impl ExternType for D {
387         type Id = type_id!("tests::D");
388         type Kind = Trivial;
389     }
390 
391     unsafe impl ExternType for E {
392         type Id = type_id!("tests::E");
393         type Kind = Opaque;
394     }
395 }
396 
397 #[derive(PartialEq, Debug)]
398 pub struct R(pub usize);
399 
400 impl R {
get(&self) -> usize401     fn get(&self) -> usize {
402         self.0
403     }
404 
set(&mut self, n: usize) -> usize405     fn set(&mut self, n: usize) -> usize {
406         self.0 = n;
407         n
408     }
409 }
410 
411 pub struct Reference<'a>(pub &'a String);
412 
413 impl ffi::Shared {
r_method_on_shared(&self) -> String414     fn r_method_on_shared(&self) -> String {
415         "2020".to_owned()
416     }
417 }
418 
419 impl ffi::Array {
r_get_array_sum(&self) -> i32420     pub fn r_get_array_sum(&self) -> i32 {
421         self.a.iter().sum()
422     }
423 }
424 
425 #[derive(Default)]
426 #[repr(C)]
427 pub struct Buffer([c_char; 12]);
428 
429 unsafe impl ExternType for Buffer {
430     type Id = type_id!("tests::Buffer");
431     type Kind = cxx::kind::Trivial;
432 }
433 
434 #[derive(Debug)]
435 struct Error;
436 
437 impl std::error::Error for Error {}
438 
439 impl Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result440     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
441         f.write_str("rust error")
442     }
443 }
444 
r_return_primitive() -> usize445 fn r_return_primitive() -> usize {
446     2020
447 }
448 
r_return_shared() -> ffi::Shared449 fn r_return_shared() -> ffi::Shared {
450     ffi::Shared { z: 2020 }
451 }
452 
r_return_box() -> Box<R>453 fn r_return_box() -> Box<R> {
454     Box::new(R(2020))
455 }
456 
r_return_unique_ptr() -> UniquePtr<ffi::C>457 fn r_return_unique_ptr() -> UniquePtr<ffi::C> {
458     extern "C" {
459         fn cxx_test_suite_get_unique_ptr() -> *mut ffi::C;
460     }
461     unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr()) }
462 }
463 
r_return_shared_ptr() -> SharedPtr<ffi::C>464 fn r_return_shared_ptr() -> SharedPtr<ffi::C> {
465     extern "C" {
466         fn cxx_test_suite_get_shared_ptr(repr: *mut SharedPtr<ffi::C>);
467     }
468     let mut shared_ptr = MaybeUninit::<SharedPtr<ffi::C>>::uninit();
469     let repr = shared_ptr.as_mut_ptr();
470     unsafe {
471         cxx_test_suite_get_shared_ptr(repr);
472         shared_ptr.assume_init()
473     }
474 }
475 
r_return_ref(shared: &ffi::Shared) -> &usize476 fn r_return_ref(shared: &ffi::Shared) -> &usize {
477     &shared.z
478 }
479 
r_return_mut(shared: &mut ffi::Shared) -> &mut usize480 fn r_return_mut(shared: &mut ffi::Shared) -> &mut usize {
481     &mut shared.z
482 }
483 
r_return_str(shared: &ffi::Shared) -> &str484 fn r_return_str(shared: &ffi::Shared) -> &str {
485     let _ = shared;
486     "2020"
487 }
488 
r_return_sliceu8(shared: &ffi::Shared) -> &[u8]489 fn r_return_sliceu8(shared: &ffi::Shared) -> &[u8] {
490     let _ = shared;
491     b"2020"
492 }
493 
r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8]494 fn r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8] {
495     slice
496 }
497 
r_return_rust_string() -> String498 fn r_return_rust_string() -> String {
499     "2020".to_owned()
500 }
501 
r_return_unique_ptr_string() -> UniquePtr<CxxString>502 fn r_return_unique_ptr_string() -> UniquePtr<CxxString> {
503     extern "C" {
504         fn cxx_test_suite_get_unique_ptr_string() -> *mut CxxString;
505     }
506     unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr_string()) }
507 }
508 
r_return_rust_vec() -> Vec<u8>509 fn r_return_rust_vec() -> Vec<u8> {
510     Vec::new()
511 }
512 
r_return_rust_vec_string() -> Vec<String>513 fn r_return_rust_vec_string() -> Vec<String> {
514     Vec::new()
515 }
516 
r_return_rust_vec_extern_struct() -> Vec<ffi::Job>517 fn r_return_rust_vec_extern_struct() -> Vec<ffi::Job> {
518     Vec::new()
519 }
520 
r_return_ref_rust_vec(shared: &ffi::Shared) -> &Vec<u8>521 fn r_return_ref_rust_vec(shared: &ffi::Shared) -> &Vec<u8> {
522     let _ = shared;
523     unimplemented!()
524 }
525 
r_return_mut_rust_vec(shared: &mut ffi::Shared) -> &mut Vec<u8>526 fn r_return_mut_rust_vec(shared: &mut ffi::Shared) -> &mut Vec<u8> {
527     let _ = shared;
528     unimplemented!()
529 }
530 
r_return_identity(n: usize) -> usize531 fn r_return_identity(n: usize) -> usize {
532     n
533 }
534 
r_return_sum(n1: usize, n2: usize) -> usize535 fn r_return_sum(n1: usize, n2: usize) -> usize {
536     n1 + n2
537 }
538 
r_return_enum(n: u32) -> ffi::Enum539 fn r_return_enum(n: u32) -> ffi::Enum {
540     if n == 0 {
541         ffi::Enum::AVal
542     } else if n <= 2020 {
543         ffi::Enum::BVal
544     } else {
545         ffi::Enum::LastVal
546     }
547 }
548 
r_take_primitive(n: usize)549 fn r_take_primitive(n: usize) {
550     assert_eq!(n, 2020);
551 }
552 
r_take_shared(shared: ffi::Shared)553 fn r_take_shared(shared: ffi::Shared) {
554     assert_eq!(shared.z, 2020);
555 }
556 
r_take_box(r: Box<R>)557 fn r_take_box(r: Box<R>) {
558     let _ = r;
559 }
560 
r_take_unique_ptr(c: UniquePtr<ffi::C>)561 fn r_take_unique_ptr(c: UniquePtr<ffi::C>) {
562     let _ = c;
563 }
564 
r_take_shared_ptr(c: SharedPtr<ffi::C>)565 fn r_take_shared_ptr(c: SharedPtr<ffi::C>) {
566     let _ = c;
567 }
568 
r_take_ref_r(r: &R)569 fn r_take_ref_r(r: &R) {
570     let _ = r;
571 }
572 
r_take_ref_c(c: &ffi::C)573 fn r_take_ref_c(c: &ffi::C) {
574     let _ = c;
575 }
576 
r_take_str(s: &str)577 fn r_take_str(s: &str) {
578     assert_eq!(s, "2020");
579 }
580 
r_take_rust_string(s: String)581 fn r_take_rust_string(s: String) {
582     assert_eq!(s, "2020");
583 }
584 
r_take_slice_char(s: &[c_char])585 fn r_take_slice_char(s: &[c_char]) {
586     assert_eq!(s.len(), 5);
587     let s = cast::c_char_to_unsigned(s);
588     assert_eq!(std::str::from_utf8(s).unwrap(), "2020\0");
589 }
590 
r_take_unique_ptr_string(s: UniquePtr<CxxString>)591 fn r_take_unique_ptr_string(s: UniquePtr<CxxString>) {
592     assert_eq!(s.as_ref().unwrap().to_str().unwrap(), "2020");
593 }
594 
r_take_ref_vector(v: &CxxVector<u8>)595 fn r_take_ref_vector(v: &CxxVector<u8>) {
596     let slice = v.as_slice();
597     assert_eq!(slice, [20, 2, 0]);
598 }
599 
r_take_ref_empty_vector(v: &CxxVector<u64>)600 fn r_take_ref_empty_vector(v: &CxxVector<u64>) {
601     assert!(v.as_slice().is_empty());
602     assert!(v.is_empty());
603 }
604 
r_take_rust_vec(v: Vec<u8>)605 fn r_take_rust_vec(v: Vec<u8>) {
606     let _ = v;
607 }
608 
r_take_rust_vec_string(v: Vec<String>)609 fn r_take_rust_vec_string(v: Vec<String>) {
610     let _ = v;
611 }
612 
r_take_ref_rust_vec(v: &Vec<u8>)613 fn r_take_ref_rust_vec(v: &Vec<u8>) {
614     let _ = v;
615 }
616 
r_take_ref_rust_vec_string(v: &Vec<String>)617 fn r_take_ref_rust_vec_string(v: &Vec<String>) {
618     let _ = v;
619 }
620 
r_take_enum(e: ffi::Enum)621 fn r_take_enum(e: ffi::Enum) {
622     let _ = e;
623 }
624 
r_try_return_void() -> Result<(), Error>625 fn r_try_return_void() -> Result<(), Error> {
626     Ok(())
627 }
628 
r_try_return_primitive() -> Result<usize, Error>629 fn r_try_return_primitive() -> Result<usize, Error> {
630     Ok(2020)
631 }
632 
r_try_return_box() -> Result<Box<R>, Error>633 fn r_try_return_box() -> Result<Box<R>, Error> {
634     Ok(Box::new(R(2020)))
635 }
636 
r_fail_return_primitive() -> Result<usize, Error>637 fn r_fail_return_primitive() -> Result<usize, Error> {
638     Err(Error)
639 }
640 
r_try_return_sliceu8(slice: &[u8]) -> Result<&[u8], Error>641 fn r_try_return_sliceu8(slice: &[u8]) -> Result<&[u8], Error> {
642     Ok(slice)
643 }
644 
r_try_return_mutsliceu8(slice: &mut [u8]) -> Result<&mut [u8], Error>645 fn r_try_return_mutsliceu8(slice: &mut [u8]) -> Result<&mut [u8], Error> {
646     Ok(slice)
647 }
648 
r_aliased_function(x: i32) -> String649 fn r_aliased_function(x: i32) -> String {
650     x.to_string()
651 }
652