I'm dealing with some FFI codes, so I need to use pointers, now I have a struct like this:
struct Foo {
i_pointer: *const i32, // just for example, the real case is *const c_void
i: i32,
}
impl Foo {
pub fn new() -> Arc<Foo> {
let mut arc_foo = Arc::new(Foo {
i_pointer: std::ptr::null(),
i: 0,
});
let foo = Arc::get_mut(&mut arc_foo).unwrap();
foo.i_pointer = &foo.i as *const _;
arc_foo
}
}
And for more safety, since this is a typical self-referenced struct, I decide to use Pin
to forbid the movement of the object.
Since Pin
has no effort on Unpin
objects, the first step I decide to do is make my type cancel the Unpin
trait implement like this:
struct Foo {
i_pointer: *const i32,
i: i32,
_pin: PhantomPinned,
}
And the new
function become to this:
impl Foo {
pub fn new() -> Arc<Pin<Foo>> {
let mut arc_foo = Arc::new(Pin::new(Foo {
i_pointer: std::ptr::null(),
i: 0,
_pin: Default::default()
}));
let pin = Arc::get_mut(&mut arc_foo).unwrap();
...
arc_foo
}
}
But I suddenly have no idea how to write.
The first problem is that the type Foo
is not implement Deref
:
error[E0277]: the trait bound `Foo: Deref` is not satisfied
--> src\main.rs:22:45
|
22 | let mut arc_foo = Arc::new(Pin::new(Foo {
| ____________________________________--------_^
| | |
| | required by a bound introduced by this call
23 | | i_pointer: std::ptr::null(),
24 | | i: 0,
25 | | _pin: Default::default()
26 | | }));
| |_________^ expected an implementor of trait `Deref`
|
note: required by a bound in `Pin::<P>::new`
--> C:\Users\psion\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\pin.rs:482:9
|
482 | impl<P: Deref<Target: Unpin>> Pin<P> {
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Pin::<P>::new`
help: consider borrowing here
|
22 | let mut arc_foo = Arc::new(Pin::new(&Foo {
| +
22 | let mut arc_foo = Arc::new(Pin::new(&mut Foo {
| ++++
But I don't know how to write, since I already use _pin: PhantomPinned,
to cancel the Unpin
impl, how can I make a Unpin
deref?
So what is the right way to design a fn new() -> Arc<Pin<Foo>>
in my case?