diff --git a/src/lib.rs b/src/lib.rs index 7f4d664..6bad76f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -408,6 +408,7 @@ macro_rules! self_cell { type JoinedCell<'a> = $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'a>>; let layout = $crate::alloc::alloc::Layout::new::(); + assert!(layout.size() != 0); let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap(); @@ -447,6 +448,7 @@ macro_rules! self_cell { type JoinedCell<'a> = $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'a>>; let layout = $crate::alloc::alloc::Layout::new::(); + assert!(layout.size() != 0); let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap(); @@ -506,6 +508,7 @@ macro_rules! self_cell { type JoinedCell<'a> = $crate::unsafe_self_cell::JoinedCell<$Owner, $Dependent<'a>>; let layout = $crate::alloc::alloc::Layout::new::(); + assert!(layout.size() != 0); let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap(); diff --git a/tests/self_cell.rs b/tests/self_cell.rs index 035c678..21cd4a4 100644 --- a/tests/self_cell.rs +++ b/tests/self_cell.rs @@ -3,6 +3,8 @@ #![deny(private_in_public)] use std::fmt::Debug; +use std::marker::PhantomData; +use std::panic::catch_unwind; use std::rc::Rc; use crossbeam_utils::thread; @@ -219,14 +221,6 @@ fn catch_panic_in_from() { } } - // impl<'a> TryInto> for &'a Owner { - // type Error = Box; - - // fn try_into(self) -> Result, Self::Error> { - // std::panic::catch_unwind(|| PanicCtor::new(&self)) - // } - // } - self_cell!( struct NoLeakCell { owner: Owner, @@ -242,7 +236,7 @@ fn catch_panic_in_from() { let owner = Owner("This string is no trout".into()); let ast_cell_result = NoLeakCell::try_new(owner.clone(), |owner| { - std::panic::catch_unwind(|| PanicCtor::new(&owner)) + catch_unwind(|| PanicCtor::new(&owner)) }); assert!(ast_cell_result.is_err()); } @@ -440,6 +434,36 @@ fn into_owner() { // assert_eq!(ast_cell.borrow_owner(), &expected_body); } +#[test] +fn zero_size_cell() { + struct ZeroSizeRef<'a>(PhantomData<&'a ()>); + + self_cell!( + struct ZeroSizeCell { + owner: (), + + #[covariant] + dependent: ZeroSizeRef, + } + ); + + assert!(catch_unwind(|| ZeroSizeCell::new((), |_| ZeroSizeRef(PhantomData))).is_err()); + + assert!( + catch_unwind(|| ZeroSizeCell::try_new((), |_| -> Result<_, i32> { + Ok(ZeroSizeRef(PhantomData)) + })) + .is_err() + ); + + assert!(catch_unwind( + || ZeroSizeCell::try_new_or_recover((), |_| -> Result<_, i32> { + Ok(ZeroSizeRef(PhantomData)) + }) + ) + .is_err()); +} + #[test] fn share_across_threads() { // drop_joined takes &mut self, so that's not a thread concern anyway.