Skip to content

Commit 5a0ad9d

Browse files
authored
Merge pull request #859 from dtolnay/vectorrepr
Fix "not FFI-safe" on CxxVector containing struct containing Rust string
2 parents 78c0c68 + db90502 commit 5a0ad9d

File tree

4 files changed

+19
-8
lines changed

4 files changed

+19
-8
lines changed

macro/src/expand.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,10 +1593,10 @@ fn expand_cxx_vector(
15931593
#[link_name = #link_push_back]
15941594
fn __push_back #impl_generics(
15951595
this: ::std::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
1596-
value: &mut ::std::mem::ManuallyDrop<#elem #ty_generics>,
1596+
value: *mut ::std::ffi::c_void,
15971597
);
15981598
}
1599-
__push_back(this, value);
1599+
__push_back(this, value as *mut ::std::mem::ManuallyDrop<Self> as *mut ::std::ffi::c_void);
16001600
}
16011601
#[doc(hidden)]
16021602
unsafe fn __pop_back(
@@ -1607,10 +1607,10 @@ fn expand_cxx_vector(
16071607
#[link_name = #link_pop_back]
16081608
fn __pop_back #impl_generics(
16091609
this: ::std::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
1610-
out: &mut ::std::mem::MaybeUninit<#elem #ty_generics>,
1610+
out: *mut ::std::ffi::c_void,
16111611
);
16121612
}
1613-
__pop_back(this, out);
1613+
__pop_back(this, out as *mut ::std::mem::MaybeUninit<Self> as *mut ::std::ffi::c_void);
16141614
}
16151615
})
16161616
} else {
@@ -1635,9 +1635,12 @@ fn expand_cxx_vector(
16351635
unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<Self>, pos: usize) -> *mut Self {
16361636
extern "C" {
16371637
#[link_name = #link_get_unchecked]
1638-
fn __get_unchecked #impl_generics(_: *mut ::cxx::CxxVector<#elem #ty_generics>, _: usize) -> *mut #elem #ty_generics;
1638+
fn __get_unchecked #impl_generics(
1639+
v: *mut ::cxx::CxxVector<#elem #ty_generics>,
1640+
pos: usize,
1641+
) -> *mut ::std::ffi::c_void;
16391642
}
1640-
__get_unchecked(v, pos)
1643+
__get_unchecked(v, pos) as *mut Self
16411644
}
16421645
#by_value_methods
16431646
#[doc(hidden)]

src/cxx_vector.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ use core::slice;
2323
/// pointer, as in `&CxxVector<T>` or `UniquePtr<CxxVector<T>>`.
2424
#[repr(C, packed)]
2525
pub struct CxxVector<T> {
26-
_private: [T; 0],
26+
// A thing, because repr(C) structs are not allowed to consist exclusively
27+
// of PhantomData fields.
28+
_void: [c_void; 0],
29+
// The conceptual vector elements to ensure that autotraits are propagated
30+
// correctly, e.g. CxxVector is UnwindSafe iff T is.
31+
_elements: PhantomData<[T]>,
32+
// Prevent unpin operation from Pin<&mut CxxVector<T>> to &mut CxxVector<T>.
2733
_pinned: PhantomData<PhantomPinned>,
2834
}
2935

tests/ffi/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ pub mod ffi {
326326
}
327327

328328
impl Box<Shared> {}
329+
impl CxxVector<SharedString> {}
329330
}
330331

331332
mod other {

tests/ui/vector_autotraits.stderr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ note: required because it appears within the type `NotThreadSafe`
1515
|
1616
7 | type NotThreadSafe;
1717
| ^^^^^^^^^^^^^
18-
= note: required because it appears within the type `[NotThreadSafe; 0]`
18+
= note: required because it appears within the type `[NotThreadSafe]`
19+
= note: required because it appears within the type `PhantomData<[NotThreadSafe]>`
1920
= note: required because it appears within the type `CxxVector<NotThreadSafe>`

0 commit comments

Comments
 (0)