diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-12-11 18:44:00 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-12-11 18:44:00 -0300 |
commit | f1e7d76c7ce610b6a1e9e66cdd6cfa78436ab511 (patch) | |
tree | 66183146b4ecb748ae5890da1330c7193f112775 | |
parent | 72841de072c4a904983e9eb631b690a61d3e06ff (diff) |
Add tests for moving the pin
-rw-r--r-- | tests/movable.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/tests/movable.rs b/tests/movable.rs new file mode 100644 index 0000000..f702979 --- /dev/null +++ b/tests/movable.rs @@ -0,0 +1,58 @@ +//! Tests of "moving" a holder. +//! +//! We cannot move the actual holders themselves but we can move owned handles +//! (Box, Rc, etc) to them. + +use std::cell::Cell; +use std::rc::Rc; + +use selfref::Holder; +use selfref::opaque; + +struct Foo<'this> { + foo: Cell<Option<&'this Foo<'this>>>, +} + +struct FooKey; + +opaque! { + impl Opaque for FooKey { + type Kind<'this> = Foo<'this>; + } +} + +fn create_holder() -> Holder<'static, FooKey> { + Holder::new_with(|builder| builder.build(Foo { + foo: Cell::new(None), + })) +} + +#[test] +fn move_box() { + // this is UB without the !Unpin hack + // same goes for any pinned container that has &mut's to it. + let b1 = Box::pin(create_holder()); + b1.as_ref().operate_in(|foo| { + foo.foo.set(Some(foo.get_ref())); + }); + let b2 = b1; + b2.as_ref().operate_in(|foo| { + // check that we can access the self-reference + assert!(foo.foo.get().unwrap().foo.get().is_some()); + }); +} + +#[test] +fn move_rc() { + // this is perfectly fine without the !Unpin hack! + // any container that behaves like a shared ref is fine for this. + let b1 = Rc::pin(create_holder()); + b1.as_ref().operate_in(|foo| { + foo.foo.set(Some(foo.get_ref())); + }); + let b2 = b1; + b2.as_ref().operate_in(|foo| { + // check that we can access the self-reference + assert!(foo.foo.get().unwrap().foo.get().is_some()); + }); +} |