cxx
cxx copied to clipboard
Raw pointers as receivers
Hi!
Let me add a question.
I'd like to ask why raw pointers *const T and *mut T as receivers are unsupported?
What I often want to write is the FFI methods as
pub fn unsafe allies(self: *const Game) -> &Playerset;
// or
pub fn unsafe allies(self: *const Game) -> *mut Playerset;
but currently to make sure the shim generated by CXX fits the foreign API I have to write it as
pub fn allies(self: Pin<&mut Game>) -> Pin<&mut Playerset>;
This however brings not much safety to the call, since I need to (unsafely) dereference the foreign pointer on the Rust adapter side: https://github.com/nlinker/bwapi-xi/blob/3c9a1cc3fd2f546be21462408834923451671a39/library/src/bw/game.rs#L28-L35
So my question is whether raw pointers as receivers were switched off by design or just they have the low priority for the current time (and one may create a PR supporting this potentially)?
That seems fine to allow. Nobody has needed it so far.
That seems fine to allow. Nobody has needed it so far.
Thanks! I'm making the PR, not great progress so far, but I keep trying :-)
I hit this too. AFAICT if a C++ API has:
class Foo { void foo(); }
then there is no way to safely call it from Rust with a &Foo. The obvious way is
impl Foo {
unsafe fn unsafe_pin(&self) -> Pin<&mut Foo> {
mem::transmute(self)
}
fn oops(&self) {
unsafe { self.unsafe_pin().foo() }
}
}
but calling unsafe_pin() is insta-UB, as there's a &Foo and a &mut Foo alive simultaneously.
In practice, I think the UB won't be triggered by existing Rust (and Miri agrees: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=aafa32d497a9738378db0c096510f51e), but I don't see any way round it.
The way to avoid the UB would be to use UnsafeCell, something like:
struct Foo(UnsafeCell<ffi::Foo>);
unsafe fn unsafe_pin(&self) -> Pin<&mut ffi::Foo> {
Pin::unchecked_new(&mut *self.0.get())
}