From f1e7d76c7ce610b6a1e9e66cdd6cfa78436ab511 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 11 Dec 2022 18:44:00 -0300 Subject: Add tests for moving the pin --- tests/movable.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/movable.rs (limited to 'tests/movable.rs') 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>>, +} + +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()); + }); +} -- cgit 1.4.1