diff --git a/library/Cargo.lock b/library/Cargo.lock index 47fbf5169f491..4689c78a98f7d 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -28,6 +28,7 @@ version = "0.0.0" dependencies = [ "compiler_builtins", "core", + "safety", ] [[package]] @@ -67,6 +68,9 @@ dependencies = [ [[package]] name = "core" version = "0.0.0" +dependencies = [ + "safety", +] [[package]] name = "coretests" @@ -196,6 +200,39 @@ dependencies = [ "unwind", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + [[package]] name = "proc_macro" version = "0.0.0" @@ -212,6 +249,15 @@ dependencies = [ "cc", ] +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + [[package]] name = "r-efi" version = "5.3.0" @@ -296,6 +342,16 @@ dependencies = [ "std", ] +[[package]] +name = "safety" +version = "0.1.0" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "shlex" version = "1.3.0" @@ -324,6 +380,7 @@ dependencies = [ "rand", "rand_xorshift", "rustc-demangle", + "safety", "std_detect", "unwind", "vex-sdk", @@ -341,6 +398,27 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sysroot" version = "0.0.0" @@ -361,6 +439,12 @@ dependencies = [ "std", ] +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + [[package]] name = "unwind" version = "0.0.0" @@ -380,6 +464,12 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "vex-sdk" version = "0.27.0" diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 11abf49c8b391..827e7d69f7b4e 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -176,6 +176,7 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(optimize_attribute)] +#![feature(proc_macro_hygiene)] #![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] #![feature(slice_internals)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 2b62b92d43886..0002bb98c76a2 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -251,6 +251,8 @@ use core::hash::{Hash, Hasher}; use core::intrinsics::abort; #[cfg(not(no_global_oom_handling))] use core::iter; +#[cfg(kani)] +use core::kani; use core::marker::{PhantomData, Unsize}; use core::mem::{self, ManuallyDrop, align_of_val_raw}; use core::num::NonZeroUsize; @@ -1195,6 +1197,20 @@ impl Rc, A> { /// ``` #[stable(feature = "new_uninit", since = "1.82.0")] #[inline] + #[cfg_attr( + // Kani 0.65 limitation: proof_for_contract cannot target this + // MaybeUninit-based generic impl reliably. Verified via kani::proof + // harnesses (verify_1198 / verify_1239) with explicit postcondition checks. + kani, + kani::requires({ + let p = Rc::, A>::as_ptr(&self); + kani::mem::can_dereference(p) + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &Rc| Rc::::strong_count(result) >= 1) + )] pub unsafe fn assume_init(self) -> Rc { let (ptr, alloc) = Rc::into_inner_with_allocator(self); unsafe { Rc::from_inner_in(ptr.cast(), alloc) } @@ -1233,6 +1249,20 @@ impl Rc<[mem::MaybeUninit], A> { /// ``` #[stable(feature = "new_uninit", since = "1.82.0")] #[inline] + #[cfg_attr( + // Kani 0.65 limitation: proof_for_contract cannot target this + // MaybeUninit-based generic impl reliably. Verified via kani::proof + // harnesses (verify_1198 / verify_1239) with explicit postcondition checks. + kani, + kani::requires({ + let p = Rc::<[mem::MaybeUninit], A>::as_ptr(&self); + kani::mem::can_dereference(p) + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &Rc<[T], A>| Rc::<[T], A>::strong_count(result) >= 1) + )] pub unsafe fn assume_init(self) -> Rc<[T], A> { let (ptr, alloc) = Rc::into_inner_with_allocator(self); unsafe { Rc::from_ptr_in(ptr.as_ptr() as _, alloc) } @@ -1303,6 +1333,19 @@ impl Rc { /// ``` #[inline] #[stable(feature = "rc_raw", since = "1.17.0")] + #[cfg_attr( + kani, + kani::requires({ + let offset = unsafe { data_offset(ptr) }; + let inner = unsafe { ptr.byte_sub(offset) as *const RcInner }; + let rebuilt_ptr = unsafe { &raw const (*inner).value }; + + kani::mem::checked_align_of_raw(ptr).is_some() + && kani::mem::checked_size_of_raw(ptr).is_some() + && ptr == rebuilt_ptr + && unsafe { (*inner).strong.get() >= 1 } + }) + )] pub unsafe fn from_raw(ptr: *const T) -> Self { unsafe { Self::from_raw_in(ptr, Global) } } @@ -1363,6 +1406,23 @@ impl Rc { /// ``` #[inline] #[stable(feature = "rc_mutate_strong_count", since = "1.53.0")] + #[cfg_attr(kani, kani::requires(!ptr.is_null()))] + #[cfg_attr(kani, kani::requires(kani::mem::can_dereference(ptr)))] + #[cfg_attr(kani, kani::requires({ + let offset = unsafe { data_offset(ptr) }; + let rc_ptr = ptr.byte_sub(offset) as *const RcInner; + kani::mem::can_dereference(rc_ptr) + }))] + #[cfg_attr(kani, kani::requires({ + let offset = unsafe { data_offset(ptr) }; + let rc_ptr = ptr.byte_sub(offset) as *const RcInner; + kani::mem::can_dereference(rc_ptr) && unsafe { (*rc_ptr).strong.get() >= 1 } + }))] + #[cfg_attr(kani, kani::modifies({ + let offset = unsafe { data_offset(ptr) }; + let rc_ptr = ptr.byte_sub(offset) as *const RcInner; + unsafe { &raw const (*rc_ptr).strong } + }))] pub unsafe fn increment_strong_count(ptr: *const T) { unsafe { Self::increment_strong_count_in(ptr, Global) } } @@ -1400,6 +1460,34 @@ impl Rc { /// ``` #[inline] #[stable(feature = "rc_mutate_strong_count", since = "1.53.0")] + #[cfg_attr( + kani, + kani::requires({ + let offset = unsafe { data_offset(ptr) }; + let inner_mut = unsafe { ptr.byte_sub(offset) as *mut RcInner }; + let inner = inner_mut as *const RcInner; + let rebuilt_ptr = unsafe { &raw const (*inner).value }; + let strong_ptr = unsafe { &raw mut (*inner_mut).strong }; + + let into_raw_roundtrip_ptr = { + let rc = unsafe { Rc::::from_raw(ptr) }; + Rc::::into_raw(rc) + }; + + ptr == rebuilt_ptr + && ptr == into_raw_roundtrip_ptr + && kani::mem::checked_size_of_raw(ptr) + == Some(unsafe { mem::size_of_val_raw(rebuilt_ptr) }) + && kani::mem::checked_align_of_raw(ptr) + == Some(unsafe { align_of_val_raw(rebuilt_ptr) }) + && unsafe { (*strong_ptr).get() >= 1 } + }) + )] + #[cfg_attr(kani, kani::modifies({ + let offset = unsafe { data_offset(ptr) }; + let rc_ptr = ptr.byte_sub(offset) as *const RcInner; + unsafe { &raw const (*rc_ptr).strong } + }))] pub unsafe fn decrement_strong_count(ptr: *const T) { unsafe { Self::decrement_strong_count_in(ptr, Global) } } @@ -1540,6 +1628,25 @@ impl Rc { /// } /// ``` #[unstable(feature = "allocator_api", issue = "32838")] + #[cfg_attr( + kani, + kani::requires({ + let offset = unsafe { data_offset(ptr) }; + let inner = unsafe { ptr.byte_sub(offset) as *const RcInner }; + let rebuilt_ptr = unsafe { &raw const (*inner).value }; + + ptr == rebuilt_ptr + && kani::mem::checked_size_of_raw(ptr) + == Some(unsafe { mem::size_of_val_raw(rebuilt_ptr) }) + && kani::mem::checked_align_of_raw(ptr) + == Some(unsafe { align_of_val_raw(rebuilt_ptr) }) + && unsafe { (*inner).strong.get() >= 1 } + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &Self| Rc::::as_ptr(result) == ptr) + )] pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { let offset = unsafe { data_offset(ptr) }; @@ -1644,6 +1751,35 @@ impl Rc { /// ``` #[inline] #[unstable(feature = "allocator_api", issue = "32838")] + #[cfg_attr( + kani, + kani::requires({ + let offset = unsafe { data_offset(ptr) }; + let inner_mut = unsafe { ptr.byte_sub(offset) as *mut RcInner }; + let inner = inner_mut as *const RcInner; + let rebuilt_ptr = unsafe { &raw const (*inner).value }; + let strong_ptr = unsafe { &raw mut (*inner_mut).strong }; + + let into_raw_roundtrip_ptr = { + let rc = unsafe { Rc::::from_raw_in(ptr, alloc.clone()) }; + let (raw_ptr, _raw_alloc) = Rc::::into_raw_with_allocator(rc); + raw_ptr + }; + + ptr == rebuilt_ptr + && ptr == into_raw_roundtrip_ptr + && kani::mem::checked_size_of_raw(ptr) + == Some(unsafe { mem::size_of_val_raw(rebuilt_ptr) }) + && kani::mem::checked_align_of_raw(ptr) + == Some(unsafe { align_of_val_raw(rebuilt_ptr) }) + && unsafe { (*strong_ptr).get() >= 1 } + }) + )] + #[cfg_attr(kani, kani::modifies({ + let offset = unsafe { data_offset(ptr) }; + let rc_ptr = ptr.byte_sub(offset) as *const RcInner; + unsafe { &raw const (*rc_ptr).strong } + }))] pub unsafe fn increment_strong_count_in(ptr: *const T, alloc: A) where A: Clone, @@ -1690,6 +1826,29 @@ impl Rc { /// ``` #[inline] #[unstable(feature = "allocator_api", issue = "32838")] + #[cfg_attr( + kani, + kani::requires({ + let offset = unsafe { data_offset(ptr) }; + let inner_mut = unsafe { ptr.byte_sub(offset) as *mut RcInner }; + let inner = inner_mut as *const RcInner; + let rebuilt_ptr = unsafe { &raw const (*inner).value }; + + let strong_ptr = unsafe { &raw mut (*inner_mut).strong }; + + ptr == rebuilt_ptr + && kani::mem::checked_size_of_raw(ptr) + == Some(unsafe { mem::size_of_val_raw(rebuilt_ptr) }) + && kani::mem::checked_align_of_raw(ptr) + == Some(unsafe { align_of_val_raw(rebuilt_ptr) }) + && unsafe { (*strong_ptr).get() >= 1 } + }) + )] + #[cfg_attr(kani, kani::modifies({ + let offset = unsafe { data_offset(ptr) }; + let rc_ptr = ptr.byte_sub(offset) as *const RcInner; + unsafe { &raw const (*rc_ptr).strong } + }))] pub unsafe fn decrement_strong_count_in(ptr: *const T, alloc: A) { unsafe { drop(Rc::from_raw_in(ptr, alloc)) }; } @@ -1793,6 +1952,25 @@ impl Rc { /// ``` #[inline] #[unstable(feature = "get_mut_unchecked", issue = "63292")] + #[cfg_attr( + kani, + kani::requires({ + let inner = this.ptr.as_ptr(); + let value = unsafe { &raw mut (*inner).value }; + + kani::mem::can_dereference(inner) + && kani::mem::can_dereference(value) + && kani::mem::can_write(value) + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &&mut T| { + let inner = old(this.ptr.as_ptr()); + let value = unsafe { &raw const (*inner).value }; + core::ptr::addr_eq((*result) as *const T, value) + }) + )] pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T { // We are careful to *not* create a reference covering the "count" fields, as // this would conflict with accesses to the reference counts (e.g. by `Weak`). @@ -2026,6 +2204,7 @@ impl Rc { /// [`downcast`]: Self::downcast #[inline] #[unstable(feature = "downcast_unchecked", issue = "90850")] + #[cfg_attr(kani, kani::requires((*self).is::()))] pub unsafe fn downcast_unchecked(self) -> Rc { unsafe { let (ptr, alloc) = Rc::into_inner_with_allocator(self); @@ -2182,11 +2361,27 @@ impl Rc<[T]> { let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 }; + #[cfg(not(kani))] for (i, item) in iter.enumerate() { ptr::write(elems.add(i), item); guard.n_elems += 1; } + #[cfg(kani)] + { + // Kani needs an explicit loop so it can attach loop contracts. + let mut iter = iter; + let mut i = 0usize; + + #[kani::loop_invariant(i == guard.n_elems)] + #[kani::loop_modifies(&i, &guard.n_elems, ptr::slice_from_raw_parts_mut(elems, len))] + while let Some(item) = iter.next() { + ptr::write(elems.add(i), item); + i += 1; + guard.n_elems += 1; + } + } + // All clear. Forget the guard so it doesn't free the new RcInner. mem::forget(guard); @@ -3122,6 +3317,63 @@ impl Weak { /// [`new`]: Weak::new #[inline] #[stable(feature = "weak_into_raw", since = "1.45.0")] + #[cfg_attr( + kani, + kani::requires({ + let is_sentinel = is_dangling(ptr); + if is_sentinel { + true + } else { + let offset = unsafe { data_offset(ptr) }; + let inner = unsafe { ptr.byte_sub(offset) as *const RcInner }; + let rebuilt_ptr = unsafe { &raw const (*inner).value }; + + kani::mem::same_allocation(ptr.cast::(), inner.cast::()) + && ptr == rebuilt_ptr + && kani::mem::can_dereference(unsafe { &raw const (*inner).strong }) + && kani::mem::can_dereference(unsafe { &raw const (*inner).weak }) + } + }) + )] + #[cfg_attr( + kani, + kani::requires({ + let is_sentinel = is_dangling(ptr); + is_sentinel || { + let offset = unsafe { data_offset(ptr) }; + let inner = unsafe { ptr.byte_sub(offset) as *const RcInner }; + unsafe { (*inner).weak.get() > 0 } + } + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &Self| { + if old(is_dangling(ptr)) { + (result.ptr.as_ptr().cast::<()>()).addr() == usize::MAX + && (result.as_ptr().cast::<()>()).addr() == usize::MAX + } else { + result.as_ptr() == ptr + && result.ptr.as_ptr() + == old({ + let offset = unsafe { data_offset(ptr) }; + unsafe { ptr.byte_sub(offset) as *mut RcInner } + }) + } + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &Self| { + old(is_dangling(ptr)) + || unsafe { (*result.ptr.as_ptr()).weak.get() } + == old({ + let offset = unsafe { data_offset(ptr) }; + let inner = unsafe { ptr.byte_sub(offset) as *const RcInner }; + unsafe { (*inner).weak.get() } + }) + }) + )] pub unsafe fn from_raw(ptr: *const T) -> Self { unsafe { Self::from_raw_in(ptr, Global) } } @@ -3294,6 +3546,53 @@ impl Weak { /// [`new`]: Weak::new #[inline] #[unstable(feature = "allocator_api", issue = "32838")] + #[cfg_attr( + kani, + kani::requires({ + let is_sentinel = is_dangling(ptr); + if is_sentinel { + true + } else { + let offset = unsafe { data_offset(ptr) }; + let inner = unsafe { ptr.byte_sub(offset) as *const RcInner }; + let rebuilt_ptr = unsafe { &raw const (*inner).value }; + + kani::mem::same_allocation(ptr.cast::(), inner.cast::()) + && ptr == rebuilt_ptr + && kani::mem::can_dereference(unsafe { &raw const (*inner).strong }) + && kani::mem::can_dereference(unsafe { &raw const (*inner).weak }) + && unsafe { (*inner).weak.get() > 0 } + } + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &Self| { + if old(is_dangling(ptr)) { + (result.ptr.as_ptr().cast::<()>()).addr() == usize::MAX + && (result.as_ptr().cast::<()>()).addr() == usize::MAX + } else { + result.as_ptr() == ptr + && result.ptr.as_ptr() + == old({ + let offset = unsafe { data_offset(ptr) }; + unsafe { ptr.byte_sub(offset) as *mut RcInner } + }) + } + }) + )] + #[cfg_attr( + kani, + kani::ensures(|result: &Self| { + old(is_dangling(ptr)) + || unsafe { (*result.ptr.as_ptr()).weak.get() } + == old({ + let offset = unsafe { data_offset(ptr) }; + let inner = unsafe { ptr.byte_sub(offset) as *const RcInner }; + unsafe { (*inner).weak.get() } + }) + }) + )] pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { // See Weak::as_ptr for context on how the input pointer is derived. @@ -3472,7 +3771,11 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Weak { /// assert!(other_weak_foo.upgrade().is_none()); /// ``` fn drop(&mut self) { - let inner = if let Some(inner) = self.inner() { inner } else { return }; + let inner = if let Some(inner) = self.inner() { + inner + } else { + return; + }; inner.dec_weak(); // the weak count starts at 1, and will only go to zero if all @@ -4160,3 +4463,4400 @@ impl Drop for UniqueRcUninit { } } } + +// ========================================================================= +// Challenge 26: Verify reference-counted Cell implementation harnesses +// ========================================================================= + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod kani_rc_harness_helpers { + use super::*; + + pub(super) fn verifier_nondet_vec() -> Vec { + let cap: usize = kani::any(); + let elem_layout = Layout::new::(); + kani::assume(elem_layout.repeat(cap).is_ok()); + let mut v = Vec::::with_capacity(cap); + unsafe { + let sz: usize = kani::any(); + kani::assume(sz <= cap); + v.set_len(sz); + ptr::write_bytes(v.as_mut_ptr().cast::(), kani::any::(), mem::size_of::() * sz); + } + v + } + + pub(super) fn rc_slice_layout_ok(len: usize) -> bool { + Layout::array::(len) + .and_then(|value_layout| Layout::new::>().extend(value_layout).map(|_| ())) + .is_ok() + } + + pub(super) fn nondet_rc_slice(vec: &Vec) -> &[T] { + let len = vec.len(); + kani::assume(rc_slice_layout_ok::(len)); + vec.as_slice() + } + + pub(super) fn verifier_nondet_vec_rc() -> Vec { + let vec = verifier_nondet_vec(); + kani::assume(rc_slice_layout_ok::(vec.len())); + vec + } + + pub(super) fn verifier_nondet_zeroed_uninit_rc_slice() -> Rc<[mem::MaybeUninit], Global> { + let len = kani::any_where(|l: &usize| rc_slice_layout_ok::(*l)); + Rc::<[T]>::new_zeroed_slice(len) + } +} + +// === UNSAFE FUNCTIONS (12 — all required) === + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1198 { + use super::*; + + // Kani 0.65 limitation: proof_for_contract cannot resolve paths for + // impl Rc, A> — the macro fails to map + // MaybeUninit back to the impl's generic parameter T. + // These harnesses use #[kani::proof] instead; the requires clause + // is still checked as an assertion at the call site, and we manually + // assert the postcondition (*init == value) below. + + macro_rules! gen_assume_init_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $ty = kani::any::<$ty>(); + let expected = value.clone(); + let mut uninit: Rc, Global> = Rc::new_uninit_in(Global); + Rc::get_mut(&mut uninit).unwrap().write(value); + let init: Rc<$ty, Global> = unsafe { uninit.assume_init() }; + assert_eq!(&*init, &expected); + } + }; + } + + gen_assume_init_harness!(harness_assume_init_i8, i8); + gen_assume_init_harness!(harness_assume_init_i16, i16); + gen_assume_init_harness!(harness_assume_init_i32, i32); + gen_assume_init_harness!(harness_assume_init_i64, i64); + gen_assume_init_harness!(harness_assume_init_i128, i128); + gen_assume_init_harness!(harness_assume_init_u8, u8); + gen_assume_init_harness!(harness_assume_init_u16, u16); + gen_assume_init_harness!(harness_assume_init_u32, u32); + gen_assume_init_harness!(harness_assume_init_u64, u64); + gen_assume_init_harness!(harness_assume_init_u128, u128); + gen_assume_init_harness!(harness_assume_init_unit, ()); + gen_assume_init_harness!(harness_assume_init_array, [u8; 4]); + gen_assume_init_harness!(harness_assume_init_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1239 { + use super::kani_rc_harness_helpers::*; + use super::*; + + // Kani 0.65 limitation: proof_for_contract cannot resolve paths for + // impl Rc<[MaybeUninit], A> (same issue as verify_1198). + // Uses #[kani::proof]; requires is checked as assertion at call site. + + // Kani cannot express the full "all elements are initialized" predicate for + // arbitrary `T`. This harness models the caller-side safety requirement of + // `assume_init` with a byte-level witness: it explicitly writes the backing + // bytes before converting the allocation to `Rc<[MaybeUninit]>`. + + fn exercise_assume_init_slice() { + let len = kani::any_where(|l: &usize| rc_slice_layout_ok::(*l)); + let mut initialized = Vec::, Global>::with_capacity(len); + unsafe { + initialized.set_len(len); + ptr::write_bytes( + initialized.as_mut_ptr().cast::(), + kani::any::(), + mem::size_of::() * len, + ); + } + let uninit: Rc<[mem::MaybeUninit], Global> = Rc::from(initialized); + let expected_data = (&*uninit).as_ptr() as *const T; + let expected_len = uninit.len(); + let result: Rc<[T], Global> = unsafe { uninit.assume_init() }; + + assert_eq!((&*result).as_ptr(), expected_data); + assert_eq!(result.len(), expected_len); + assert_eq!(Rc::strong_count(&result), 1); + } + + macro_rules! gen_assume_init_slice_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + exercise_assume_init_slice::<$elem>(); + } + }; + } + + gen_assume_init_slice_harness!(harness_assume_init_slice_i8, i8); + gen_assume_init_slice_harness!(harness_assume_init_slice_i16, i16); + gen_assume_init_slice_harness!(harness_assume_init_slice_i32, i32); + gen_assume_init_slice_harness!(harness_assume_init_slice_i64, i64); + gen_assume_init_slice_harness!(harness_assume_init_slice_i128, i128); + gen_assume_init_slice_harness!(harness_assume_init_slice_u8, u8); + gen_assume_init_slice_harness!(harness_assume_init_slice_u16, u16); + gen_assume_init_slice_harness!(harness_assume_init_slice_u32, u32); + gen_assume_init_slice_harness!(harness_assume_init_slice_u64, u64); + gen_assume_init_slice_harness!(harness_assume_init_slice_u128, u128); + gen_assume_init_slice_harness!(harness_assume_init_slice_unit, ()); + gen_assume_init_slice_harness!(harness_assume_init_slice_array, [u8; 4]); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1327 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_from_raw_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::<$ty>::from_raw)] + pub fn $name() { + let value: $ty = kani::any(); + let rc: Rc<$ty> = Rc::new(value); + let ptr: *const $ty = Rc::into_raw(rc); + let _: Rc<$ty> = unsafe { Rc::from_raw(ptr) }; + } + }; + } + + macro_rules! gen_from_raw_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::<[$elem]>::from_raw)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem]> = Rc::from(vec); + let ptr: *const [$elem] = Rc::into_raw(rc); + let _: Rc<[$elem]> = unsafe { Rc::from_raw(ptr) }; + } + }; + } + + gen_from_raw_sized_harness!(harness_rc_from_raw_i8, i8); + gen_from_raw_sized_harness!(harness_rc_from_raw_i16, i16); + gen_from_raw_sized_harness!(harness_rc_from_raw_i32, i32); + gen_from_raw_sized_harness!(harness_rc_from_raw_i64, i64); + gen_from_raw_sized_harness!(harness_rc_from_raw_i128, i128); + gen_from_raw_sized_harness!(harness_rc_from_raw_u8, u8); + gen_from_raw_sized_harness!(harness_rc_from_raw_u16, u16); + gen_from_raw_sized_harness!(harness_rc_from_raw_u32, u32); + gen_from_raw_sized_harness!(harness_rc_from_raw_u64, u64); + gen_from_raw_sized_harness!(harness_rc_from_raw_u128, u128); + gen_from_raw_sized_harness!(harness_rc_from_raw_bool, bool); + gen_from_raw_sized_harness!(harness_rc_from_raw_unit, ()); + gen_from_raw_sized_harness!(harness_rc_from_raw_array, [u8; 4]); + + gen_from_raw_unsized_harness!(harness_rc_from_raw_vec_u8, u8); + gen_from_raw_unsized_harness!(harness_rc_from_raw_vec_u16, u16); + gen_from_raw_unsized_harness!(harness_rc_from_raw_vec_u32, u32); + gen_from_raw_unsized_harness!(harness_rc_from_raw_vec_u64, u64); + gen_from_raw_unsized_harness!(harness_rc_from_raw_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1403 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_increment_strong_count_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::<$ty>::increment_strong_count)] + pub fn $name() { + let value: $ty = kani::any(); + let rc: Rc<$ty> = Rc::new(value); + let ptr: *const $ty = Rc::into_raw(rc); + unsafe { + Rc::<$ty>::increment_strong_count(ptr); + let _recovered: Rc<$ty> = Rc::from_raw(ptr); + Rc::<$ty>::decrement_strong_count(ptr); + } + } + }; + } + + macro_rules! gen_increment_strong_count_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::<[$elem]>::increment_strong_count)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem]> = Rc::from(vec); + let ptr: *const [$elem] = Rc::into_raw(rc); + unsafe { + Rc::<[$elem]>::increment_strong_count(ptr); + let _recovered: Rc<[$elem]> = Rc::from_raw(ptr); + Rc::<[$elem]>::decrement_strong_count(ptr); + } + } + }; + } + + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_i8, i8); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_i16, i16); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_i32, i32); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_i64, i64); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_i128, i128); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_u8, u8); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_u16, u16); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_u32, u32); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_u64, u64); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_u128, u128); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_bool, bool); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_unit, ()); + gen_increment_strong_count_sized_harness!(harness_increment_strong_count_array, [u8; 4]); + + gen_increment_strong_count_unsized_harness!(harness_increment_strong_count_vec_u8, u8); + gen_increment_strong_count_unsized_harness!(harness_increment_strong_count_vec_u16, u16); + gen_increment_strong_count_unsized_harness!(harness_increment_strong_count_vec_u32, u32); + gen_increment_strong_count_unsized_harness!(harness_increment_strong_count_vec_u64, u64); + gen_increment_strong_count_unsized_harness!(harness_increment_strong_count_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1486 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_decrement_strong_count_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::<$ty>::decrement_strong_count)] + pub fn $name() { + let value: $ty = kani::any(); + let rc: Rc<$ty> = Rc::new(value); + let ptr: *const $ty = Rc::into_raw(rc); + unsafe { + Rc::<$ty>::increment_strong_count(ptr); + Rc::<$ty>::decrement_strong_count(ptr); + let _: Rc<$ty> = Rc::from_raw(ptr); + } + } + }; + } + + macro_rules! gen_decrement_strong_count_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::<[$elem]>::decrement_strong_count)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem]> = Rc::from(vec); + let ptr: *const [$elem] = Rc::into_raw(rc); + unsafe { + Rc::<[$elem]>::increment_strong_count(ptr); + Rc::<[$elem]>::decrement_strong_count(ptr); + let _: Rc<[$elem]> = Rc::from_raw(ptr); + } + } + }; + } + + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_i8, i8); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_i16, i16); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_i32, i32); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_i64, i64); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_i128, i128); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_u8, u8); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_u16, u16); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_u32, u32); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_u64, u64); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_u128, u128); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_bool, bool); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_unit, ()); + gen_decrement_strong_count_sized_harness!(harness_rc_decrement_strong_count_array, [u8; 4]); + + gen_decrement_strong_count_unsized_harness!(harness_rc_decrement_strong_count_vec_u8, u8); + gen_decrement_strong_count_unsized_harness!(harness_rc_decrement_strong_count_vec_u16, u16); + gen_decrement_strong_count_unsized_harness!(harness_rc_decrement_strong_count_vec_u32, u32); + gen_decrement_strong_count_unsized_harness!(harness_rc_decrement_strong_count_vec_u64, u64); + gen_decrement_strong_count_unsized_harness!(harness_rc_decrement_strong_count_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1650 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_from_raw_in_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::<$ty, Global>::from_raw_in)] + pub fn $name() { + let value: $ty = kani::any(); + let rc: Rc<$ty, Global> = Rc::new_in(value, Global); + let (ptr, alloc): (*const $ty, Global) = Rc::into_raw_with_allocator(rc); + let _: Rc<$ty, Global> = unsafe { Rc::from_raw_in(ptr, alloc) }; + } + }; + } + + macro_rules! gen_from_raw_in_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::<[$elem], Global>::from_raw_in)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let (ptr, alloc): (*const [$elem], Global) = Rc::into_raw_with_allocator(rc); + let _: Rc<[$elem], Global> = unsafe { Rc::from_raw_in(ptr, alloc) }; + } + }; + } + + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_i8, i8); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_i16, i16); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_i32, i32); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_i64, i64); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_i128, i128); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_u8, u8); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_u16, u16); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_u32, u32); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_u64, u64); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_u128, u128); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_unit, ()); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_bool, bool); + gen_from_raw_in_sized_harness!(harness_rc_from_raw_in_array, [u8; 4]); + + gen_from_raw_in_unsized_harness!(harness_rc_from_raw_in_vec_u8, u8); + gen_from_raw_in_unsized_harness!(harness_rc_from_raw_in_vec_u16, u16); + gen_from_raw_in_unsized_harness!(harness_rc_from_raw_in_vec_u32, u32); + gen_from_raw_in_unsized_harness!(harness_rc_from_raw_in_vec_u64, u64); + gen_from_raw_in_unsized_harness!(harness_rc_from_raw_in_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1792 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_increment_strong_count_in_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::<$ty, Global>::increment_strong_count_in)] + pub fn $name() { + let value: $ty = kani::any(); + let rc: Rc<$ty, Global> = Rc::new_in(value, Global); + let (ptr, _alloc): (*const $ty, Global) = Rc::into_raw_with_allocator(rc); + unsafe { + Rc::<$ty, Global>::increment_strong_count_in(ptr, Global); + let _: Rc<$ty, Global> = Rc::<$ty, Global>::from_raw_in(ptr, Global); + Rc::<$ty, Global>::decrement_strong_count_in(ptr, Global); + } + } + }; + } + + macro_rules! gen_increment_strong_count_in_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::<[$elem], Global>::increment_strong_count_in)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let (ptr, _alloc): (*const [$elem], Global) = Rc::into_raw_with_allocator(rc); + unsafe { + Rc::<[$elem], Global>::increment_strong_count_in(ptr, Global); + let _: Rc<[$elem], Global> = Rc::<[$elem], Global>::from_raw_in(ptr, Global); + Rc::<[$elem], Global>::decrement_strong_count_in(ptr, Global); + } + } + }; + } + + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_i8, i8); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_i16, i16); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_i32, i32); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_i64, i64); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_i128, i128); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_u8, u8); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_u16, u16); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_u32, u32); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_u64, u64); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_u128, u128); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_bool, bool); + gen_increment_strong_count_in_sized_harness!(harness_rc_increment_strong_count_in_unit, ()); + gen_increment_strong_count_in_sized_harness!( + harness_rc_increment_strong_count_in_array, + [u8; 4] + ); + + gen_increment_strong_count_in_unsized_harness!(harness_rc_increment_strong_count_in_vec_u8, u8); + gen_increment_strong_count_in_unsized_harness!( + harness_rc_increment_strong_count_in_vec_u16, + u16 + ); + gen_increment_strong_count_in_unsized_harness!( + harness_rc_increment_strong_count_in_vec_u32, + u32 + ); + gen_increment_strong_count_in_unsized_harness!( + harness_rc_increment_strong_count_in_vec_u64, + u64 + ); + gen_increment_strong_count_in_unsized_harness!( + harness_rc_increment_strong_count_in_vec_u128, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1878 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_decrement_strong_count_in_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::<$ty, Global>::decrement_strong_count_in)] + pub fn $name() { + let value: $ty = kani::any(); + let rc: Rc<$ty, Global> = Rc::new_in(value, Global); + let rc2: Rc<$ty, Global> = rc.clone(); + let (ptr, alloc): (*const $ty, Global) = Rc::into_raw_with_allocator(rc2); + unsafe { + Rc::<$ty, Global>::decrement_strong_count_in(ptr, alloc); + } + } + }; + } + + macro_rules! gen_decrement_strong_count_in_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::<[$elem], Global>::decrement_strong_count_in)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let rc2: Rc<[$elem], Global> = rc.clone(); + let (ptr, alloc): (*const [$elem], Global) = Rc::into_raw_with_allocator(rc2); + unsafe { + Rc::<[$elem], Global>::decrement_strong_count_in(ptr, alloc); + } + } + }; + } + + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_i8, i8); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_i16, i16); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_i32, i32); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_i64, i64); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_i128, i128); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_u8, u8); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_u16, u16); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_u32, u32); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_u64, u64); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_u128, u128); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_bool, bool); + gen_decrement_strong_count_in_sized_harness!(harness_rc_decrement_strong_count_in_unit, ()); + gen_decrement_strong_count_in_sized_harness!( + harness_rc_decrement_strong_count_in_array, + [u8; 4] + ); + + gen_decrement_strong_count_in_unsized_harness!(harness_rc_decrement_strong_count_in_vec_u8, u8); + gen_decrement_strong_count_in_unsized_harness!( + harness_rc_decrement_strong_count_in_vec_u16, + u16 + ); + gen_decrement_strong_count_in_unsized_harness!( + harness_rc_decrement_strong_count_in_vec_u32, + u32 + ); + gen_decrement_strong_count_in_unsized_harness!( + harness_rc_decrement_strong_count_in_vec_u64, + u64 + ); + gen_decrement_strong_count_in_unsized_harness!( + harness_rc_decrement_strong_count_in_vec_u128, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1982 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_get_mut_unchecked_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::<$ty>::get_mut_unchecked)] + pub fn $name() { + let value: $ty = kani::any(); + let replacement: $ty = kani::any(); + let mut rc: Rc<$ty> = Rc::new(value); + unsafe { + *Rc::get_mut_unchecked(&mut rc) = replacement; + } + } + }; + } + + macro_rules! gen_get_mut_unchecked_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::<[$elem]>::get_mut_unchecked)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let mut rc: Rc<[$elem]> = Rc::from(vec); + unsafe { + let data: &mut [$elem] = Rc::get_mut_unchecked(&mut rc); + if !data.is_empty() { + data[0] = kani::any::<$elem>(); + } + } + } + }; + } + + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_i8, i8); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_i16, i16); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_i32, i32); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_i64, i64); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_i128, i128); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_u8, u8); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_u16, u16); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_u32, u32); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_u64, u64); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_u128, u128); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_bool, bool); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_unit, ()); + gen_get_mut_unchecked_sized_harness!(harness_get_mut_unchecked_array, [u8; 4]); + + gen_get_mut_unchecked_unsized_harness!(harness_get_mut_unchecked_vec_u8, u8); + gen_get_mut_unchecked_unsized_harness!(harness_get_mut_unchecked_vec_u16, u16); + gen_get_mut_unchecked_unsized_harness!(harness_get_mut_unchecked_vec_u32, u32); + gen_get_mut_unchecked_unsized_harness!(harness_get_mut_unchecked_vec_u64, u64); + gen_get_mut_unchecked_unsized_harness!(harness_get_mut_unchecked_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2216 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_downcast_unchecked_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Rc::::downcast_unchecked::<$ty>)] + pub fn $name() { + let value: $ty = kani::any(); + let rc_dyn: Rc = Rc::new_in(value, Global); + let _downcasted: Rc<$ty, Global> = unsafe { rc_dyn.downcast_unchecked::<$ty>() }; + } + }; + } + + macro_rules! gen_downcast_unchecked_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Rc::::downcast_unchecked::>)] + pub fn $name() { + let v = verifier_nondet_vec::<$elem>(); + let rc_dyn: Rc = Rc::new_in(v, Global); + let _downcasted: Rc, Global> = + unsafe { rc_dyn.downcast_unchecked::>() }; + } + }; + } + + gen_downcast_unchecked_harness!(harness_downcast_unchecked_i8, i8); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_i16, i16); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_i32, i32); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_i64, i64); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_i128, i128); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_u8, u8); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_u16, u16); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_u32, u32); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_u64, u64); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_u128, u128); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_bool, bool); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_unit, ()); + gen_downcast_unchecked_harness!(harness_downcast_unchecked_array, [u8; 4]); + + gen_downcast_unchecked_unsized_harness!(harness_downcast_unchecked_vec_u8, u8); + gen_downcast_unchecked_unsized_harness!(harness_downcast_unchecked_vec_u16, u16); + gen_downcast_unchecked_unsized_harness!(harness_downcast_unchecked_vec_u32, u32); + gen_downcast_unchecked_unsized_harness!(harness_downcast_unchecked_vec_u64, u64); + gen_downcast_unchecked_unsized_harness!(harness_downcast_unchecked_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3369 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_weak_from_raw_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Weak::<$ty>::from_raw)] + pub fn $name() { + let value: $ty = kani::any(); + let strong: Rc<$ty> = Rc::new(value); + let weak: Weak<$ty> = Rc::downgrade(&strong); + let ptr: *const $ty = weak.into_raw(); + let _recovered: Weak<$ty> = unsafe { Weak::from_raw(ptr) }; + } + }; + } + + macro_rules! gen_weak_from_raw_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Weak::<[$elem]>::from_raw)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem]> = Rc::from(vec); + let weak: Weak<[$elem]> = Rc::downgrade(&strong); + let ptr: *const [$elem] = weak.into_raw(); + let _recovered: Weak<[$elem]> = unsafe { Weak::from_raw(ptr) }; + } + }; + } + + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_i8, i8); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_i16, i16); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_i32, i32); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_i64, i64); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_i128, i128); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_u8, u8); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_u16, u16); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_u32, u32); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_u64, u64); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_u128, u128); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_bool, bool); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_unit, ()); + gen_weak_from_raw_sized_harness!(harness_weak_from_raw_array, [u8; 4]); + + gen_weak_from_raw_unsized_harness!(harness_weak_from_raw_vec_u8, u8); + gen_weak_from_raw_unsized_harness!(harness_weak_from_raw_vec_u16, u16); + gen_weak_from_raw_unsized_harness!(harness_weak_from_raw_vec_u32, u32); + gen_weak_from_raw_unsized_harness!(harness_weak_from_raw_vec_u64, u64); + gen_weak_from_raw_unsized_harness!(harness_weak_from_raw_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3588 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_weak_from_raw_in_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof_for_contract(Weak::<$ty, Global>::from_raw_in)] + pub fn $name() { + let value: $ty = kani::any(); + let strong: Rc<$ty, Global> = Rc::new_in(value, Global); + let weak: Weak<$ty, Global> = Rc::downgrade(&strong); + let (ptr, alloc): (*const $ty, Global) = weak.into_raw_with_allocator(); + let _recovered: Weak<$ty, Global> = unsafe { Weak::from_raw_in(ptr, alloc) }; + } + }; + } + + macro_rules! gen_weak_from_raw_in_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof_for_contract(Weak::<[$elem], Global>::from_raw_in)] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + let weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + let (ptr, alloc): (*const [$elem], Global) = weak.into_raw_with_allocator(); + let _recovered: Weak<[$elem], Global> = unsafe { Weak::from_raw_in(ptr, alloc) }; + } + }; + } + + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_i8, i8); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_i16, i16); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_i32, i32); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_i64, i64); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_i128, i128); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_u8, u8); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_u16, u16); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_u32, u32); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_u64, u64); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_u128, u128); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_bool, bool); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_unit, ()); + gen_weak_from_raw_in_sized_harness!(harness_weak_from_raw_in_array, [u8; 4]); + + gen_weak_from_raw_in_unsized_harness!(harness_weak_from_raw_in_vec_u8, u8); + gen_weak_from_raw_in_unsized_harness!(harness_weak_from_raw_in_vec_u16, u16); + gen_weak_from_raw_in_unsized_harness!(harness_weak_from_raw_in_vec_u32, u32); + gen_weak_from_raw_in_unsized_harness!(harness_weak_from_raw_in_vec_u64, u64); + gen_weak_from_raw_in_unsized_harness!(harness_weak_from_raw_in_vec_u128, u128); +} + +// === SAFE FUNCTIONS (51 of 54) === + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1918 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Rc::get_mut` returns `Some(&mut T)` only when the allocation is fully unique: + // `strong_count == 1` and `weak_count == 0` (`Rc::is_unique`). + // Therefore we need three harness scenarios to cover all behavior-relevant states: + // 1) unique: construct a fresh `Rc` and call `get_mut` directly; + // 2) shared: clone once so `strong_count > 1`, then call `get_mut`; + // 3) weak-present: downgrade once so `weak_count > 0` while strong stays unique, then call `get_mut`. + // The generated harnesses below realize these states explicitly for each tested type. + macro_rules! gen_get_mut_harness { + ($unique:ident, $shared:ident, $weak_present:ident, dyn Any) => { + #[kani::proof] + pub fn $unique() { + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let mut rc: Rc = rc_i32; + let _ = Rc::::get_mut(&mut rc); + } + + #[kani::proof] + pub fn $shared() { + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let mut rc: Rc = rc_i32; + let _shared: Rc = Rc::clone(&rc); + let _ = Rc::::get_mut(&mut rc); + } + + #[kani::proof] + pub fn $weak_present() { + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let mut rc: Rc = rc_i32; + let _weak: Weak = Rc::downgrade(&rc); + let _ = Rc::::get_mut(&mut rc); + } + }; + ($unique:ident, $shared:ident, $weak_present:ident, $ty:ty) => { + #[kani::proof] + pub fn $unique() { + let mut rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _ = Rc::<$ty, Global>::get_mut(&mut rc); + } + + #[kani::proof] + pub fn $shared() { + let mut rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _shared: Rc<$ty, Global> = Rc::clone(&rc); + let _ = Rc::<$ty, Global>::get_mut(&mut rc); + } + + #[kani::proof] + pub fn $weak_present() { + let mut rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _weak: Weak<$ty, Global> = Rc::downgrade(&rc); + let _ = Rc::<$ty, Global>::get_mut(&mut rc); + } + }; + } + + macro_rules! gen_get_mut_unsized_harness { + ($(#[$unique_attr:meta])* $unique:ident, $shared:ident, $weak_present:ident, $elem:ty) => { + $(#[$unique_attr])* + #[kani::proof] + pub fn $unique() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let mut rc: Rc<[$elem], Global> = Rc::from(vec); + let _ = Rc::<[$elem], Global>::get_mut(&mut rc); + } + + #[kani::proof] + pub fn $shared() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let mut rc: Rc<[$elem], Global> = Rc::from(vec); + let _shared: Rc<[$elem], Global> = Rc::clone(&rc); + let _ = Rc::<[$elem], Global>::get_mut(&mut rc); + } + + #[kani::proof] + pub fn $weak_present() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let mut rc: Rc<[$elem], Global> = Rc::from(vec); + let _weak: Weak<[$elem], Global> = Rc::downgrade(&rc); + let _ = Rc::<[$elem], Global>::get_mut(&mut rc); + } + }; + } + + gen_get_mut_harness!( + harness_get_mut_i8_unique_some, + harness_get_mut_i8_shared_none, + harness_get_mut_i8_weak_present_none, + i8 + ); + gen_get_mut_harness!( + harness_get_mut_i16_unique_some, + harness_get_mut_i16_shared_none, + harness_get_mut_i16_weak_present_none, + i16 + ); + gen_get_mut_harness!( + harness_get_mut_i32_unique_some, + harness_get_mut_i32_shared_none, + harness_get_mut_i32_weak_present_none, + i32 + ); + gen_get_mut_harness!( + harness_get_mut_i64_unique_some, + harness_get_mut_i64_shared_none, + harness_get_mut_i64_weak_present_none, + i64 + ); + gen_get_mut_harness!( + harness_get_mut_i128_unique_some, + harness_get_mut_i128_shared_none, + harness_get_mut_i128_weak_present_none, + i128 + ); + gen_get_mut_harness!( + harness_get_mut_u8_unique_some, + harness_get_mut_u8_shared_none, + harness_get_mut_u8_weak_present_none, + u8 + ); + gen_get_mut_harness!( + harness_get_mut_u16_unique_some, + harness_get_mut_u16_shared_none, + harness_get_mut_u16_weak_present_none, + u16 + ); + gen_get_mut_harness!( + harness_get_mut_u32_unique_some, + harness_get_mut_u32_shared_none, + harness_get_mut_u32_weak_present_none, + u32 + ); + gen_get_mut_harness!( + harness_get_mut_u64_unique_some, + harness_get_mut_u64_shared_none, + harness_get_mut_u64_weak_present_none, + u64 + ); + gen_get_mut_harness!( + harness_get_mut_u128_unique_some, + harness_get_mut_u128_shared_none, + harness_get_mut_u128_weak_present_none, + u128 + ); + gen_get_mut_harness!( + harness_get_mut_unit_unique_some, + harness_get_mut_unit_shared_none, + harness_get_mut_unit_weak_present_none, + () + ); + gen_get_mut_harness!( + harness_get_mut_arr_unique_some, + harness_get_mut_arr_shared_none, + harness_get_mut_arr_weak_present_none, + [u8; 4] + ); + gen_get_mut_harness!( + harness_get_mut_dyn_any_unique_some, + harness_get_mut_dyn_any_shared_none, + harness_get_mut_dyn_any_weak_present_none, + dyn Any + ); + + gen_get_mut_unsized_harness!( + harness_get_mut_vec_u8_unique_some, + harness_get_mut_vec_u8_shared_none, + harness_get_mut_vec_u8_weak_present_none, + u8 + ); + gen_get_mut_unsized_harness!( + #[cfg(not(target_os = "macos"))] + harness_get_mut_vec_u16_unique_some, + harness_get_mut_vec_u16_shared_none, + harness_get_mut_vec_u16_weak_present_none, + u16 + ); + gen_get_mut_unsized_harness!( + harness_get_mut_vec_u32_unique_some, + harness_get_mut_vec_u32_shared_none, + harness_get_mut_vec_u32_weak_present_none, + u32 + ); + gen_get_mut_unsized_harness!( + harness_get_mut_vec_u64_unique_some, + harness_get_mut_vec_u64_shared_none, + harness_get_mut_vec_u64_weak_present_none, + u64 + ); + gen_get_mut_unsized_harness!( + harness_get_mut_vec_u128_unique_some, + harness_get_mut_vec_u128_shared_none, + harness_get_mut_vec_u128_weak_present_none, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2089 { + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Rc::make_mut` has three behavior-defining states: + // 1) `strong_count == 1` and `weak_count == 0`: return mutable access in place (no clone, no move); + // 2) `strong_count != 1`: clone-on-write path, allocate/clones into a new `Rc`; + // 3) `strong_count == 1` and `weak_count != 0`: move bytes into a new allocation and + // disassociate existing `Weak`s (no value clone). + // These harnesses explicitly construct each state by: + // - unique: fresh `Rc`, direct `make_mut`; + // - shared: keep one extra strong clone alive before `make_mut`; + // - weak-present: keep one weak reference alive before `make_mut`. + macro_rules! gen_make_mut_harness { + ($unique:ident, $shared:ident, $weak_present:ident, $ty:ty) => { + #[kani::proof] + pub fn $unique() { + let mut rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _ = Rc::<$ty, Global>::make_mut(&mut rc); + } + + #[kani::proof] + pub fn $shared() { + let mut rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _shared: Rc<$ty, Global> = Rc::clone(&rc); + let _ = Rc::<$ty, Global>::make_mut(&mut rc); + } + + #[kani::proof] + pub fn $weak_present() { + let mut rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _weak: Weak<$ty, Global> = Rc::downgrade(&rc); + let _ = Rc::<$ty, Global>::make_mut(&mut rc); + } + }; + } + + macro_rules! gen_make_mut_unsized_harness { + ( + $(#[$unique_attr:meta])* + $unique:ident, + $shared:ident, + $(#[$weak_present_attr:meta])* + $weak_present:ident, + $elem:ty + ) => { + $(#[$unique_attr])* + #[kani::proof] + pub fn $unique() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let mut rc: Rc<[$elem], Global> = Rc::from(vec); + let _ = Rc::<[$elem], Global>::make_mut(&mut rc); + } + + #[kani::proof] + pub fn $shared() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let mut rc: Rc<[$elem], Global> = Rc::from(vec); + let _shared: Rc<[$elem], Global> = Rc::clone(&rc); + let _ = Rc::<[$elem], Global>::make_mut(&mut rc); + } + + $(#[$weak_present_attr])* + #[kani::proof] + pub fn $weak_present() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let mut rc: Rc<[$elem], Global> = Rc::from(vec); + let _weak: Weak<[$elem], Global> = Rc::downgrade(&rc); + let _ = Rc::<[$elem], Global>::make_mut(&mut rc); + } + }; + } + + gen_make_mut_harness!( + harness_make_mut_i8_unique, + harness_make_mut_i8_shared, + harness_make_mut_i8_weak_present, + i8 + ); + gen_make_mut_harness!( + harness_make_mut_i16_unique, + harness_make_mut_i16_shared, + harness_make_mut_i16_weak_present, + i16 + ); + gen_make_mut_harness!( + harness_make_mut_i32_unique, + harness_make_mut_i32_shared, + harness_make_mut_i32_weak_present, + i32 + ); + gen_make_mut_harness!( + harness_make_mut_i64_unique, + harness_make_mut_i64_shared, + harness_make_mut_i64_weak_present, + i64 + ); + gen_make_mut_harness!( + harness_make_mut_i128_unique, + harness_make_mut_i128_shared, + harness_make_mut_i128_weak_present, + i128 + ); + gen_make_mut_harness!( + harness_make_mut_u8_unique, + harness_make_mut_u8_shared, + harness_make_mut_u8_weak_present, + u8 + ); + gen_make_mut_harness!( + harness_make_mut_u16_unique, + harness_make_mut_u16_shared, + harness_make_mut_u16_weak_present, + u16 + ); + gen_make_mut_harness!( + harness_make_mut_u32_unique, + harness_make_mut_u32_shared, + harness_make_mut_u32_weak_present, + u32 + ); + gen_make_mut_harness!( + harness_make_mut_u64_unique, + harness_make_mut_u64_shared, + harness_make_mut_u64_weak_present, + u64 + ); + gen_make_mut_harness!( + harness_make_mut_u128_unique, + harness_make_mut_u128_shared, + harness_make_mut_u128_weak_present, + u128 + ); + gen_make_mut_harness!( + harness_make_mut_unit_unique, + harness_make_mut_unit_shared, + harness_make_mut_unit_weak_present, + () + ); + gen_make_mut_harness!( + harness_make_mut_arr4_unique, + harness_make_mut_arr4_shared, + harness_make_mut_arr4_weak_present, + [u8; 4] + ); + + gen_make_mut_unsized_harness!( + harness_make_mut_vec_u8_unique, + harness_make_mut_vec_u8_shared, + harness_make_mut_vec_u8_weak_present, + u8 + ); + gen_make_mut_unsized_harness!( + harness_make_mut_vec_u16_unique, + harness_make_mut_vec_u16_shared, + harness_make_mut_vec_u16_weak_present, + u16 + ); + gen_make_mut_unsized_harness!( + #[cfg(not(target_os = "macos"))] + harness_make_mut_vec_u32_unique, + harness_make_mut_vec_u32_shared, + #[cfg(not(target_os = "macos"))] + harness_make_mut_vec_u32_weak_present, + u32 + ); + gen_make_mut_unsized_harness!( + harness_make_mut_vec_u64_unique, + harness_make_mut_vec_u64_shared, + harness_make_mut_vec_u64_weak_present, + u64 + ); + gen_make_mut_unsized_harness!( + harness_make_mut_vec_u128_unique, + harness_make_mut_vec_u128_shared, + harness_make_mut_vec_u128_weak_present, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2201 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Rc::downcast::` has two behavior branches: + // 1) `is::() == true`: downcast succeeds and returns `Ok(Rc)`; + // 2) `is::() == false`: downcast fails and returns `Err(Rc)`. + // Each harness pair below covers both branches by: + // - success case: build `Rc` with `U == T`, coerce to `Rc`, then downcast::; + // - failure case: build `Rc` with `U != T` (here `bool`), coerce, then downcast::. + macro_rules! gen_downcast_harness { + ($success:ident, $failure:ident, $ty:ty) => { + #[kani::proof] + pub fn $success() { + let value: $ty = kani::any::<$ty>(); + let rc_value: Rc<$ty, Global> = Rc::new_in(value, Global); + let rc_any: Rc = rc_value; + let _ = Rc::::downcast::<$ty>(rc_any); + } + + #[kani::proof] + pub fn $failure() { + let rc_value: Rc = Rc::new_in(kani::any::(), Global); + let rc_any: Rc = rc_value; + let _ = Rc::::downcast::<$ty>(rc_any); + } + }; + } + + macro_rules! gen_downcast_vec_harness { + ($success:ident, $failure:ident, $elem:ty) => { + #[kani::proof] + pub fn $success() { + let value: Vec<$elem> = verifier_nondet_vec::<$elem>(); + let rc_value: Rc, Global> = Rc::new_in(value, Global); + let rc_any: Rc = rc_value; + let _ = Rc::::downcast::>(rc_any); + } + + #[kani::proof] + pub fn $failure() { + let rc_value: Rc = Rc::new_in(kani::any::(), Global); + let rc_any: Rc = rc_value; + let _ = Rc::::downcast::>(rc_any); + } + }; + } + + gen_downcast_harness!(harness_downcast_i8_success, harness_downcast_i8_failure, i8); + gen_downcast_harness!(harness_downcast_i16_success, harness_downcast_i16_failure, i16); + gen_downcast_harness!(harness_downcast_i32_success, harness_downcast_i32_failure, i32); + gen_downcast_harness!(harness_downcast_i64_success, harness_downcast_i64_failure, i64); + gen_downcast_harness!(harness_downcast_i128_success, harness_downcast_i128_failure, i128); + gen_downcast_harness!(harness_downcast_u8_success, harness_downcast_u8_failure, u8); + gen_downcast_harness!(harness_downcast_u16_success, harness_downcast_u16_failure, u16); + gen_downcast_harness!(harness_downcast_u32_success, harness_downcast_u32_failure, u32); + gen_downcast_harness!(harness_downcast_u64_success, harness_downcast_u64_failure, u64); + gen_downcast_harness!(harness_downcast_u128_success, harness_downcast_u128_failure, u128); + gen_downcast_harness!(harness_downcast_arr4_success, harness_downcast_arr4_failure, [u8; 4]); + gen_downcast_harness!(harness_downcast_unit_success, harness_downcast_unit_failure, ()); + + gen_downcast_vec_harness!(harness_downcast_vec_u8_success, harness_downcast_vec_u8_failure, u8); + gen_downcast_vec_harness!( + harness_downcast_vec_u16_success, + harness_downcast_vec_u16_failure, + u16 + ); + gen_downcast_vec_harness!( + harness_downcast_vec_u32_success, + harness_downcast_vec_u32_failure, + u32 + ); + gen_downcast_vec_harness!( + harness_downcast_vec_u64_success, + harness_downcast_vec_u64_failure, + u64 + ); + gen_downcast_vec_harness!( + harness_downcast_vec_u128_success, + harness_downcast_vec_u128_failure, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2313 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_from_box_in_harness { + ($name:ident, dyn Any) => { + #[kani::proof] + pub fn $name() { + let boxed_i32: Box = Box::new_in(kani::any::(), Global); + let src: Box = boxed_i32; + let _ = Rc::::from_box_in(src); + } + }; + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let src: Box<$ty, Global> = Box::new_in(kani::any::<$ty>(), Global); + let _ = Rc::<$ty, Global>::from_box_in(src); + } + }; + } + + macro_rules! gen_from_box_in_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let src: Box<[$elem], Global> = Box::from(vec); + let _ = Rc::<[$elem], Global>::from_box_in(src); + } + }; + } + + gen_from_box_in_harness!(harness_from_box_in_i8, i8); + gen_from_box_in_harness!(harness_from_box_in_i16, i16); + gen_from_box_in_harness!(harness_from_box_in_i32, i32); + gen_from_box_in_harness!(harness_from_box_in_i64, i64); + gen_from_box_in_harness!(harness_from_box_in_i128, i128); + gen_from_box_in_harness!(harness_from_box_in_u8, u8); + gen_from_box_in_harness!(harness_from_box_in_u16, u16); + gen_from_box_in_harness!(harness_from_box_in_u32, u32); + gen_from_box_in_harness!(harness_from_box_in_u64, u64); + gen_from_box_in_harness!(harness_from_box_in_u128, u128); + gen_from_box_in_harness!(harness_from_box_in_unit, ()); + gen_from_box_in_harness!(harness_from_box_in_arr, [u8; 4]); + gen_from_box_in_harness!(harness_from_box_in_dyn_any, dyn Any); + + gen_from_box_in_unsized_harness!(harness_from_box_in_vec_u8, u8); + gen_from_box_in_unsized_harness!(harness_from_box_in_vec_u16, u16); + gen_from_box_in_unsized_harness!(harness_from_box_in_vec_u32, u32); + gen_from_box_in_unsized_harness!(harness_from_box_in_vec_u64, u64); + gen_from_box_in_unsized_harness!(harness_from_box_in_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3502 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Weak::as_ptr` has two branches: + // 1) `is_dangling(ptr)` is true: returns the sentinel pointer itself. + // 2) `is_dangling(ptr)` is false: returns raw pointer to `RcInner::value`. + // + // Each generated pair covers both branches: + // - `*_live`: build `Weak` through `Rc::downgrade`, so pointer is non-dangling. + // - `*_dangling`: build `Weak::new_in(Global)`, so pointer is the dangling sentinel. + macro_rules! gen_weak_as_ptr_harness { + ($live:ident, $dangling:ident, dyn Any) => { + #[kani::proof] + pub fn $live() { + // `strong` stays alive in this function scope. + // `Rc::downgrade(&strong)` therefore points to a real allocation, not sentinel. + // So `Weak::as_ptr` goes to `is_dangling == false` branch. + let strong_i32: Rc = Rc::new_in(kani::any::(), Global); + let strong: Rc = strong_i32; + let weak: Weak = Rc::downgrade(&strong); + let _ptr: *const dyn Any = Weak::::as_ptr(&weak); + } + + #[kani::proof] + pub fn $dangling() { + // `Weak::new_in` constructs an empty weak with sentinel address (`usize::MAX`). + // `is_dangling` checks exactly this sentinel encoding. + // So `Weak::as_ptr` goes to `is_dangling == true` branch. + let weak_i32: Weak = Weak::new_in(Global); + let weak: Weak = weak_i32; + let _ptr: *const dyn Any = Weak::::as_ptr(&weak); + } + }; + ($live:ident, $dangling:ident, $ty:ty) => { + #[kani::proof] + pub fn $live() { + // `strong` is alive; downgrade yields a weak to the same live allocation. + // This pointer is not the sentinel, so `is_dangling` is false. + let strong: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let weak: Weak<$ty, Global> = Rc::downgrade(&strong); + let _ptr: *const $ty = Weak::<$ty, Global>::as_ptr(&weak); + } + + #[kani::proof] + pub fn $dangling() { + // `Weak::new_in(Global)` contains only the sentinel and no backing `RcInner`. + // Therefore `is_dangling` is true by construction. + let weak: Weak<$ty, Global> = Weak::new_in(Global); + let _ptr: *const $ty = Weak::<$ty, Global>::as_ptr(&weak); + } + }; + } + + // Unsized slice (`T = [E]`) also needs both branches: + // - live: `Rc<[E]> -> Weak<[E]>` via downgrade; + // - dangling: `Weak<[E; 1]>::new_in` coerced to `Weak<[E]>`. + macro_rules! gen_weak_as_ptr_unsized_harness { + ($live:ident, $dangling:ident, $elem:ty) => { + #[kani::proof] + pub fn $live() { + // `Rc::from(vec)` creates a real slice allocation. + // `downgrade` references that allocation while `strong` is alive. + // So this executes the non-dangling branch. + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + let weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + let _ptr: *const [$elem] = Weak::<[$elem], Global>::as_ptr(&weak); + } + + #[kani::proof] + pub fn $dangling() { + // Start from sentinel `Weak<[E; 1]>::new_in(Global)`. + // Coercion to `Weak<[E]>` changes metadata only; sentinel address is unchanged. + // So `is_dangling` remains true. + let weak_arr: Weak<[$elem; 1], Global> = Weak::new_in(Global); + let weak: Weak<[$elem], Global> = weak_arr; + let _ptr: *const [$elem] = Weak::<[$elem], Global>::as_ptr(&weak); + } + }; + } + + gen_weak_as_ptr_harness!(harness_weak_as_ptr_i8_live, harness_weak_as_ptr_i8_dangling, i8); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_i16_live, harness_weak_as_ptr_i16_dangling, i16); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_i32_live, harness_weak_as_ptr_i32_dangling, i32); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_i64_live, harness_weak_as_ptr_i64_dangling, i64); + gen_weak_as_ptr_harness!( + harness_weak_as_ptr_i128_live, + harness_weak_as_ptr_i128_dangling, + i128 + ); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_u8_live, harness_weak_as_ptr_u8_dangling, u8); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_u16_live, harness_weak_as_ptr_u16_dangling, u16); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_u32_live, harness_weak_as_ptr_u32_dangling, u32); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_u64_live, harness_weak_as_ptr_u64_dangling, u64); + gen_weak_as_ptr_harness!( + harness_weak_as_ptr_u128_live, + harness_weak_as_ptr_u128_dangling, + u128 + ); + gen_weak_as_ptr_harness!(harness_weak_as_ptr_unit_live, harness_weak_as_ptr_unit_dangling, ()); + gen_weak_as_ptr_harness!( + harness_weak_as_ptr_array_live, + harness_weak_as_ptr_array_dangling, + [u8; 4] + ); + gen_weak_as_ptr_harness!( + harness_weak_as_ptr_bool_live, + harness_weak_as_ptr_bool_dangling, + bool + ); + gen_weak_as_ptr_harness!( + harness_weak_as_ptr_dyn_any_live, + harness_weak_as_ptr_dyn_any_dangling, + dyn Any + ); + + gen_weak_as_ptr_unsized_harness!( + harness_weak_as_ptr_vec_u8_live, + harness_weak_as_ptr_vec_u8_dangling, + u8 + ); + gen_weak_as_ptr_unsized_harness!( + harness_weak_as_ptr_vec_u16_live, + harness_weak_as_ptr_vec_u16_dangling, + u16 + ); + gen_weak_as_ptr_unsized_harness!( + harness_weak_as_ptr_vec_u32_live, + harness_weak_as_ptr_vec_u32_dangling, + u32 + ); + gen_weak_as_ptr_unsized_harness!( + harness_weak_as_ptr_vec_u64_live, + harness_weak_as_ptr_vec_u64_dangling, + u64 + ); + gen_weak_as_ptr_unsized_harness!( + harness_weak_as_ptr_vec_u128_live, + harness_weak_as_ptr_vec_u128_dangling, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3549 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Weak::into_raw_with_allocator` itself has no explicit `if/else`, + // but it calls `Weak::as_ptr()`, whose control flow depends on weak state: + // 1) live weak (from `Rc::downgrade`) -> non-dangling payload pointer; + // 2) dangling weak (from `Weak::new_in`) -> sentinel pointer. + // + // Each harness executes: + // - `into_raw_with_allocator` to consume the weak and extract `(ptr, alloc)`; + // - `from_raw_in(ptr, alloc)` to rebuild and consume that ownership token. + // This roundtrip matches the API contract and avoids leaking the weak token. + macro_rules! gen_weak_into_raw_with_allocator_harness { + ($live:ident, $dangling:ident, dyn Any) => { + #[kani::proof] + pub fn $live() { + // Live path trigger: downgrade from an in-scope strong Rc. + let strong_i32: Rc = Rc::new_in(kani::any::(), Global); + let strong: Rc = strong_i32; + let weak: Weak = Rc::downgrade(&strong); + let (ptr, alloc): (*const dyn Any, Global) = + Weak::::into_raw_with_allocator(weak); + let _recovered: Weak = + unsafe { Weak::::from_raw_in(ptr, alloc) }; + } + + #[kani::proof] + pub fn $dangling() { + // Dangling path trigger: sentinel weak created directly. + let weak_i32: Weak = Weak::new_in(Global); + let weak: Weak = weak_i32; + let (ptr, alloc): (*const dyn Any, Global) = + Weak::::into_raw_with_allocator(weak); + let _recovered: Weak = + unsafe { Weak::::from_raw_in(ptr, alloc) }; + } + }; + ($live:ident, $dangling:ident, $ty:ty) => { + #[kani::proof] + pub fn $live() { + // Live path trigger: downgrade from a live strong Rc. + let strong: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let weak: Weak<$ty, Global> = Rc::downgrade(&strong); + let (ptr, alloc): (*const $ty, Global) = + Weak::<$ty, Global>::into_raw_with_allocator(weak); + let _recovered: Weak<$ty, Global> = + unsafe { Weak::<$ty, Global>::from_raw_in(ptr, alloc) }; + } + + #[kani::proof] + pub fn $dangling() { + // Dangling path trigger: sentinel weak from `new_in`. + let weak: Weak<$ty, Global> = Weak::new_in(Global); + let (ptr, alloc): (*const $ty, Global) = + Weak::<$ty, Global>::into_raw_with_allocator(weak); + let _recovered: Weak<$ty, Global> = + unsafe { Weak::<$ty, Global>::from_raw_in(ptr, alloc) }; + } + }; + } + + // Unsized (`T = [E]`) also covers two states: + // - live: build `Rc<[E]>`, then downgrade; + // - dangling: start from sentinel `Weak<[E; 1]>` and coerce to `Weak<[E]>`. + macro_rules! gen_weak_into_raw_with_allocator_unsized_harness { + ($live:ident, $dangling:ident, $elem:ty) => { + #[kani::proof] + pub fn $live() { + // Live unsized path: weak points into a real slice allocation. + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + let weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + let (ptr, alloc): (*const [$elem], Global) = + Weak::<[$elem], Global>::into_raw_with_allocator(weak); + let _recovered: Weak<[$elem], Global> = + unsafe { Weak::<[$elem], Global>::from_raw_in(ptr, alloc) }; + } + + #[kani::proof] + pub fn $dangling() { + // Dangling unsized path: sentinel survives coercion array -> slice. + let weak_arr: Weak<[$elem; 1], Global> = Weak::new_in(Global); + let weak: Weak<[$elem], Global> = weak_arr; + let (ptr, alloc): (*const [$elem], Global) = + Weak::<[$elem], Global>::into_raw_with_allocator(weak); + let _recovered: Weak<[$elem], Global> = + unsafe { Weak::<[$elem], Global>::from_raw_in(ptr, alloc) }; + } + }; + } + + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_i8_live, + harness_weak_into_raw_with_allocator_i8_dangling, + i8 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_i16_live, + harness_weak_into_raw_with_allocator_i16_dangling, + i16 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_i32_live, + harness_weak_into_raw_with_allocator_i32_dangling, + i32 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_i64_live, + harness_weak_into_raw_with_allocator_i64_dangling, + i64 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_i128_live, + harness_weak_into_raw_with_allocator_i128_dangling, + i128 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_u8_live, + harness_weak_into_raw_with_allocator_u8_dangling, + u8 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_u16_live, + harness_weak_into_raw_with_allocator_u16_dangling, + u16 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_u32_live, + harness_weak_into_raw_with_allocator_u32_dangling, + u32 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_u64_live, + harness_weak_into_raw_with_allocator_u64_dangling, + u64 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_u128_live, + harness_weak_into_raw_with_allocator_u128_dangling, + u128 + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_unit_live, + harness_weak_into_raw_with_allocator_unit_dangling, + () + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_arr_live, + harness_weak_into_raw_with_allocator_arr_dangling, + [u8; 4] + ); + gen_weak_into_raw_with_allocator_harness!( + harness_weak_into_raw_with_allocator_dyn_any_live, + harness_weak_into_raw_with_allocator_dyn_any_dangling, + dyn Any + ); + + gen_weak_into_raw_with_allocator_unsized_harness!( + harness_weak_into_raw_with_allocator_vec_u8_live, + harness_weak_into_raw_with_allocator_vec_u8_dangling, + u8 + ); + gen_weak_into_raw_with_allocator_unsized_harness!( + harness_weak_into_raw_with_allocator_vec_u16_live, + harness_weak_into_raw_with_allocator_vec_u16_dangling, + u16 + ); + gen_weak_into_raw_with_allocator_unsized_harness!( + harness_weak_into_raw_with_allocator_vec_u32_live, + harness_weak_into_raw_with_allocator_vec_u32_dangling, + u32 + ); + gen_weak_into_raw_with_allocator_unsized_harness!( + harness_weak_into_raw_with_allocator_vec_u64_live, + harness_weak_into_raw_with_allocator_vec_u64_dangling, + u64 + ); + gen_weak_into_raw_with_allocator_unsized_harness!( + harness_weak_into_raw_with_allocator_vec_u128_live, + harness_weak_into_raw_with_allocator_vec_u128_dangling, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3696 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Weak::upgrade` has three behavior paths: + // 1) `self.inner()?` returns `None` (dangling sentinel weak): returns `None`. + // 2) `inner` exists but `inner.strong() == 0`: returns `None`. + // 3) `inner.strong() > 0`: increments strong count and returns `Some(Rc<...>)`. + // + // The generated harnesses explicitly cover all three paths: + // - `*_live`: keep one strong owner alive -> path (3) + // - `*_strong_zero`: create weak, then drop the strong owner -> path (2) + // - `*_dangling`: construct sentinel weak with `Weak::new_in` -> path (1) + macro_rules! gen_weak_upgrade_harness { + ($live:ident, $strong_zero:ident, $dangling:ident, dyn Any) => { + #[kani::proof] + pub fn $live() { + // Path (3): `downgrade` from a live strong Rc means `inner` exists + // and strong count is at least 1. + let strong_i32: Rc = Rc::new_in(kani::any::(), Global); + let strong: Rc = strong_i32; + let weak: Weak = Rc::downgrade(&strong); + let _ = Weak::::upgrade(&weak); + } + + #[kani::proof] + pub fn $strong_zero() { + // Path (2): `weak` points to a real allocation, then all strong owners are dropped. + // `inner` still exists, but `inner.strong() == 0`. + let strong_i32: Rc = Rc::new_in(kani::any::(), Global); + let strong: Rc = strong_i32; + let weak: Weak = Rc::downgrade(&strong); + drop(strong); + let _ = Weak::::upgrade(&weak); + } + + #[kani::proof] + pub fn $dangling() { + // Path (1): sentinel weak has no backing allocation, so `inner()` returns `None`. + let weak_i32: Weak = Weak::new_in(Global); + let weak: Weak = weak_i32; + let _ = Weak::::upgrade(&weak); + } + }; + ($live:ident, $strong_zero:ident, $dangling:ident, $ty:ty) => { + #[kani::proof] + pub fn $live() { + // Path (3): live strong owner is still in scope. + let strong: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let weak: Weak<$ty, Global> = Rc::downgrade(&strong); + let _ = Weak::<$ty, Global>::upgrade(&weak); + } + + #[kani::proof] + pub fn $strong_zero() { + // Path (2): drop all strong owners after creating weak. + let strong: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let weak: Weak<$ty, Global> = Rc::downgrade(&strong); + drop(strong); + let _ = Weak::<$ty, Global>::upgrade(&weak); + } + + #[kani::proof] + pub fn $dangling() { + // Path (1): sentinel weak from `new_in`. + let weak: Weak<$ty, Global> = Weak::new_in(Global); + let _ = Weak::<$ty, Global>::upgrade(&weak); + } + }; + } + + // Unsized slice (`T = [E]`) with the same 3-path coverage strategy. + macro_rules! gen_weak_upgrade_unsized_harness { + ($live:ident, $strong_zero:ident, $dangling:ident, $elem:ty) => { + #[kani::proof] + pub fn $live() { + // Path (3): downgrade from a live `Rc<[E]>`. + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + let weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + let _ = Weak::<[$elem], Global>::upgrade(&weak); + } + + #[kani::proof] + pub fn $strong_zero() { + // Path (2): weak points to allocation, then strong owner is dropped. + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + let weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + drop(strong); + let _ = Weak::<[$elem], Global>::upgrade(&weak); + } + + #[kani::proof] + pub fn $dangling() { + // Path (1): sentinel weak coerced from `[E; 1]` to `[E]`. + let weak_arr: Weak<[$elem; 1], Global> = Weak::new_in(Global); + let weak: Weak<[$elem], Global> = weak_arr; + let _ = Weak::<[$elem], Global>::upgrade(&weak); + } + }; + } + + gen_weak_upgrade_harness!( + harness_weak_upgrade_i8_live, + harness_weak_upgrade_i8_strong_zero, + harness_weak_upgrade_i8_dangling, + i8 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_i16_live, + harness_weak_upgrade_i16_strong_zero, + harness_weak_upgrade_i16_dangling, + i16 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_i32_live, + harness_weak_upgrade_i32_strong_zero, + harness_weak_upgrade_i32_dangling, + i32 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_i64_live, + harness_weak_upgrade_i64_strong_zero, + harness_weak_upgrade_i64_dangling, + i64 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_i128_live, + harness_weak_upgrade_i128_strong_zero, + harness_weak_upgrade_i128_dangling, + i128 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_u8_live, + harness_weak_upgrade_u8_strong_zero, + harness_weak_upgrade_u8_dangling, + u8 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_u16_live, + harness_weak_upgrade_u16_strong_zero, + harness_weak_upgrade_u16_dangling, + u16 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_u32_live, + harness_weak_upgrade_u32_strong_zero, + harness_weak_upgrade_u32_dangling, + u32 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_u64_live, + harness_weak_upgrade_u64_strong_zero, + harness_weak_upgrade_u64_dangling, + u64 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_u128_live, + harness_weak_upgrade_u128_strong_zero, + harness_weak_upgrade_u128_dangling, + u128 + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_unit_live, + harness_weak_upgrade_unit_strong_zero, + harness_weak_upgrade_unit_dangling, + () + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_array_live, + harness_weak_upgrade_array_strong_zero, + harness_weak_upgrade_array_dangling, + [u8; 4] + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_bool_live, + harness_weak_upgrade_bool_strong_zero, + harness_weak_upgrade_bool_dangling, + bool + ); + gen_weak_upgrade_harness!( + harness_weak_upgrade_dyn_any_live, + harness_weak_upgrade_dyn_any_strong_zero, + harness_weak_upgrade_dyn_any_dangling, + dyn Any + ); + + gen_weak_upgrade_unsized_harness!( + harness_weak_upgrade_vec_u8_live, + harness_weak_upgrade_vec_u8_strong_zero, + harness_weak_upgrade_vec_u8_dangling, + u8 + ); + gen_weak_upgrade_unsized_harness!( + harness_weak_upgrade_vec_u16_live, + harness_weak_upgrade_vec_u16_strong_zero, + harness_weak_upgrade_vec_u16_dangling, + u16 + ); + gen_weak_upgrade_unsized_harness!( + harness_weak_upgrade_vec_u32_live, + harness_weak_upgrade_vec_u32_strong_zero, + harness_weak_upgrade_vec_u32_dangling, + u32 + ); + gen_weak_upgrade_unsized_harness!( + harness_weak_upgrade_vec_u64_live, + harness_weak_upgrade_vec_u64_strong_zero, + harness_weak_upgrade_vec_u64_dangling, + u64 + ); + gen_weak_upgrade_unsized_harness!( + harness_weak_upgrade_vec_u128_live, + harness_weak_upgrade_vec_u128_strong_zero, + harness_weak_upgrade_vec_u128_dangling, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3745 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Weak::inner` has exactly two branches: + // 1) `is_dangling(self.ptr.as_ptr()) == true` -> `None` + // 2) `is_dangling(self.ptr.as_ptr()) == false` -> `Some(WeakInner { strong, weak })` + // + // Coverage strategy: + // - `*_some`: create a live weak via `Rc::downgrade(&strong)` so pointer is non-sentinel. + // - `*_none`: create a sentinel weak via `Weak::new_in(Global)` so pointer is dangling. + macro_rules! gen_weak_inner_harness { + ($some:ident, $none:ident, dyn Any) => { + #[kani::proof] + pub fn $some() { + // Branch (2): live strong owner keeps allocation alive, so `downgrade` + // yields non-dangling weak and `inner()` must go through `Some(...)`. + let strong_i32: Rc = Rc::new_in(kani::any::(), Global); + let strong: Rc = strong_i32; + let weak: Weak = Rc::downgrade(&strong); + let _inner = Weak::::inner(&weak); + } + + #[kani::proof] + pub fn $none() { + // Branch (1): `Weak::new_in` encodes sentinel dangling pointer, so + // `is_dangling(...)` is true and `inner()` returns `None`. + let weak_i32: Weak = Weak::new_in(Global); + let weak: Weak = weak_i32; + let _inner = Weak::::inner(&weak); + } + }; + ($some:ident, $none:ident, $ty:ty) => { + #[kani::proof] + pub fn $some() { + // Branch (2): downgrade from a live strong Rc. + let strong: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let weak: Weak<$ty, Global> = Rc::downgrade(&strong); + let _inner = Weak::<$ty, Global>::inner(&weak); + } + + #[kani::proof] + pub fn $none() { + // Branch (1): sentinel weak created directly. + let weak: Weak<$ty, Global> = Weak::new_in(Global); + let _inner = Weak::<$ty, Global>::inner(&weak); + } + }; + } + + // Unsized (`T = [E]`) with the same two-branch coverage. + macro_rules! gen_weak_inner_unsized_harness { + ($some:ident, $none:ident, $elem:ty) => { + #[kani::proof] + pub fn $some() { + // Branch (2): non-dangling unsized weak from live `Rc<[E]>`. + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + let weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + let _inner = Weak::<[$elem], Global>::inner(&weak); + } + + #[kani::proof] + pub fn $none() { + // Branch (1): sentinel weak remains dangling after array->slice coercion. + let weak_arr: Weak<[$elem; 1], Global> = Weak::new_in(Global); + let weak: Weak<[$elem], Global> = weak_arr; + let _inner = Weak::<[$elem], Global>::inner(&weak); + } + }; + } + + gen_weak_inner_harness!(harness_weak_inner_i8_some, harness_weak_inner_i8_none, i8); + gen_weak_inner_harness!(harness_weak_inner_i16_some, harness_weak_inner_i16_none, i16); + gen_weak_inner_harness!(harness_weak_inner_i32_some, harness_weak_inner_i32_none, i32); + gen_weak_inner_harness!(harness_weak_inner_i64_some, harness_weak_inner_i64_none, i64); + gen_weak_inner_harness!(harness_weak_inner_i128_some, harness_weak_inner_i128_none, i128); + gen_weak_inner_harness!(harness_weak_inner_u8_some, harness_weak_inner_u8_none, u8); + gen_weak_inner_harness!(harness_weak_inner_u16_some, harness_weak_inner_u16_none, u16); + gen_weak_inner_harness!(harness_weak_inner_u32_some, harness_weak_inner_u32_none, u32); + gen_weak_inner_harness!(harness_weak_inner_u64_some, harness_weak_inner_u64_none, u64); + gen_weak_inner_harness!(harness_weak_inner_u128_some, harness_weak_inner_u128_none, u128); + gen_weak_inner_harness!(harness_weak_inner_unit_some, harness_weak_inner_unit_none, ()); + gen_weak_inner_harness!(harness_weak_inner_array_some, harness_weak_inner_array_none, [u8; 4]); + gen_weak_inner_harness!(harness_weak_inner_bool_some, harness_weak_inner_bool_none, bool); + gen_weak_inner_harness!( + harness_weak_inner_dyn_any_some, + harness_weak_inner_dyn_any_none, + dyn Any + ); + + gen_weak_inner_unsized_harness!( + harness_weak_inner_vec_u8_some, + harness_weak_inner_vec_u8_none, + u8 + ); + gen_weak_inner_unsized_harness!( + harness_weak_inner_vec_u16_some, + harness_weak_inner_vec_u16_none, + u16 + ); + gen_weak_inner_unsized_harness!( + harness_weak_inner_vec_u32_some, + harness_weak_inner_vec_u32_none, + u32 + ); + gen_weak_inner_unsized_harness!( + harness_weak_inner_vec_u64_some, + harness_weak_inner_vec_u64_none, + u64 + ); + gen_weak_inner_unsized_harness!( + harness_weak_inner_vec_u128_some, + harness_weak_inner_vec_u128_none, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3835 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Drop for Weak` executes the following decision chain: + // 1) `self.inner()` checks whether `self.ptr` is sentinel-dangling. + // - dangling (`Weak::new_in`) => `None` => return immediately. + // 2) if `inner` exists, drop always calls `inner.dec_weak()`. + // 3) then it checks post-decrement `inner.weak()`: + // - `== 0` => this weak was the last one => deallocate `RcInner`. + // - `!= 0` => some weak still exists => do not deallocate. + // + // Harness mapping: + // - `*_live`: keep `strong` alive while dropping one explicit weak + // -> after `dec_weak`, the implicit weak owned by strong pointers remains + // -> `inner.weak() != 0` branch. + // - `*_after_strong_drop`: create weak, then drop all strong owners before weak drop + // -> now this explicit weak is last weak token + // -> `dec_weak` makes count zero -> deallocation branch. + // - `*_dangling`: construct sentinel weak via `Weak::new_in` + // -> `inner()` is `None` -> early return branch. + macro_rules! gen_drop_weak_harness { + ($live:ident, $after_drop:ident, $dangling:ident, dyn Any) => { + #[kani::proof] + pub fn $live() { + // Create one strong owner (`strong`), which implies one implicit weak. + let strong_i32: Rc = Rc::new_in(kani::any::(), Global); + let strong: Rc = strong_i32; + { + // Create one explicit weak; it is dropped at scope end. + let _weak: Weak = Rc::downgrade(&strong); + } + // Dropping `_weak` runs `Drop for Weak`. + // `strong` is still alive here, so implicit weak still exists. + // Therefore post-`dec_weak` weak count is non-zero => no deallocate branch. + } + + #[kani::proof] + pub fn $after_drop() { + // Create strong owner and one explicit weak. + let strong_i32: Rc = Rc::new_in(kani::any::(), Global); + let strong: Rc = strong_i32; + let weak: Weak = Rc::downgrade(&strong); + // Drop all strong owners first, removing the implicit weak. + drop(strong); + // Now `weak` is the last weak token. + // Dropping it triggers `dec_weak` to zero => deallocate branch. + let _ = weak; + } + + #[kani::proof] + pub fn $dangling() { + // `Weak::new_in` creates sentinel-dangling weak; no `RcInner` exists. + let weak_i32: Weak = Weak::new_in(Global); + let weak: Weak = weak_i32; + // Dropping this weak calls `inner()`, which returns `None`, + // so drop returns early without touching counters or deallocating. + let _ = weak; + } + }; + ($live:ident, $after_drop:ident, $dangling:ident, $ty:ty) => { + #[kani::proof] + pub fn $live() { + // Keep one strong owner alive. + let strong: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + { + // Create explicit weak and let it drop at block end. + let _weak: Weak<$ty, Global> = Rc::downgrade(&strong); + } + // Step C: strong owner still exists, so drop follows non-zero weak branch. + } + + #[kani::proof] + pub fn $after_drop() { + // Create explicit weak from strong owner. + let strong: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let weak: Weak<$ty, Global> = Rc::downgrade(&strong); + // Remove all strong owners first. + drop(strong); + // Explicit weak is now last weak => drop deallocates. + let _ = weak; + } + + #[kani::proof] + pub fn $dangling() { + // Create sentinel weak with no allocation behind it. + let weak: Weak<$ty, Global> = Weak::new_in(Global); + // Dropping it triggers early-return path (`inner() == None`). + let _ = weak; + } + }; + } + + // Unsized slice (`T = [E]`) follows the exact same three-path state machine. + // The only difference is construction: + // - live / after-strong-drop use `Rc<[E]>` from nondet vec; + // - dangling uses sentinel `Weak<[E; 1]>` coerced to `Weak<[E]>`. + macro_rules! gen_drop_weak_unsized_harness { + ($live:ident, $after_drop:ident, $dangling:ident, $elem:ty) => { + #[kani::proof] + pub fn $live() { + // Build live slice allocation and keep strong owner alive. + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + { + // Create explicit weak and let it drop immediately. + let _weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + } + // Implicit weak still exists via strong owner => non-zero weak branch. + } + + #[kani::proof] + pub fn $after_drop() { + // Create explicit weak from live strong slice owner. + let vec = verifier_nondet_vec_rc::<$elem>(); + let strong: Rc<[$elem], Global> = Rc::from(vec); + let weak: Weak<[$elem], Global> = Rc::downgrade(&strong); + // Drop strong owner first. + drop(strong); + // Explicit weak is last weak => drop reaches deallocate branch. + let _ = weak; + } + + #[kani::proof] + pub fn $dangling() { + // Build sentinel dangling weak in sized form. + let weak_arr: Weak<[$elem; 1], Global> = Weak::new_in(Global); + // Coerce metadata to slice form; pointer remains sentinel. + let weak: Weak<[$elem], Global> = weak_arr; + // Dropping weak triggers early-return (`inner() == None`). + let _ = weak; + } + }; + } + + gen_drop_weak_harness!( + harness_drop_weak_i8_live, + harness_drop_weak_i8_after_strong_drop, + harness_drop_weak_i8_dangling, + i8 + ); + gen_drop_weak_harness!( + harness_drop_weak_i16_live, + harness_drop_weak_i16_after_strong_drop, + harness_drop_weak_i16_dangling, + i16 + ); + gen_drop_weak_harness!( + harness_drop_weak_i32_live, + harness_drop_weak_i32_after_strong_drop, + harness_drop_weak_i32_dangling, + i32 + ); + gen_drop_weak_harness!( + harness_drop_weak_i64_live, + harness_drop_weak_i64_after_strong_drop, + harness_drop_weak_i64_dangling, + i64 + ); + gen_drop_weak_harness!( + harness_drop_weak_i128_live, + harness_drop_weak_i128_after_strong_drop, + harness_drop_weak_i128_dangling, + i128 + ); + gen_drop_weak_harness!( + harness_drop_weak_u8_live, + harness_drop_weak_u8_after_strong_drop, + harness_drop_weak_u8_dangling, + u8 + ); + gen_drop_weak_harness!( + harness_drop_weak_u16_live, + harness_drop_weak_u16_after_strong_drop, + harness_drop_weak_u16_dangling, + u16 + ); + gen_drop_weak_harness!( + harness_drop_weak_u32_live, + harness_drop_weak_u32_after_strong_drop, + harness_drop_weak_u32_dangling, + u32 + ); + gen_drop_weak_harness!( + harness_drop_weak_u64_live, + harness_drop_weak_u64_after_strong_drop, + harness_drop_weak_u64_dangling, + u64 + ); + gen_drop_weak_harness!( + harness_drop_weak_u128_live, + harness_drop_weak_u128_after_strong_drop, + harness_drop_weak_u128_dangling, + u128 + ); + gen_drop_weak_harness!( + harness_drop_weak_unit_live, + harness_drop_weak_unit_after_strong_drop, + harness_drop_weak_unit_dangling, + () + ); + gen_drop_weak_harness!( + harness_drop_weak_array_live, + harness_drop_weak_array_after_strong_drop, + harness_drop_weak_array_dangling, + [u8; 4] + ); + gen_drop_weak_harness!( + harness_drop_weak_bool_live, + harness_drop_weak_bool_after_strong_drop, + harness_drop_weak_bool_dangling, + bool + ); + gen_drop_weak_harness!( + harness_drop_weak_dyn_any_live, + harness_drop_weak_dyn_any_after_strong_drop, + harness_drop_weak_dyn_any_dangling, + dyn Any + ); + + gen_drop_weak_unsized_harness!( + harness_drop_weak_vec_u8_live, + harness_drop_weak_vec_u8_after_strong_drop, + harness_drop_weak_vec_u8_dangling, + u8 + ); + gen_drop_weak_unsized_harness!( + harness_drop_weak_vec_u16_live, + harness_drop_weak_vec_u16_after_strong_drop, + harness_drop_weak_vec_u16_dangling, + u16 + ); + gen_drop_weak_unsized_harness!( + harness_drop_weak_vec_u32_live, + harness_drop_weak_vec_u32_after_strong_drop, + harness_drop_weak_vec_u32_dangling, + u32 + ); + gen_drop_weak_unsized_harness!( + harness_drop_weak_vec_u64_live, + harness_drop_weak_vec_u64_after_strong_drop, + harness_drop_weak_vec_u64_dangling, + u64 + ); + gen_drop_weak_unsized_harness!( + harness_drop_weak_vec_u128_live, + harness_drop_weak_vec_u128_after_strong_drop, + harness_drop_weak_vec_u128_dangling, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3929 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `inc_strong` has two behavior paths: + // 1) non-overflow path: `strong.wrapping_add(1) != 0`, then return normally; + // 2) overflow path: `strong.wrapping_add(1) == 0`, then call `abort()`. + // + // Coverage strategy in this module: + // - `*_non_overflow` harnesses build normal live `Rc` values, so strong starts from a valid + // non-zero count and follows path (1). + // - `harness_inc_strong_overflow_should_panic` forges `strong == usize::MAX` right before the + // call, so `wrapping_add` becomes 0 and path (2) is forced. + macro_rules! gen_inc_strong_non_overflow_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + // Build a valid live Rc. This guarantees the precondition `strong != 0`. + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let inner = rc.inner(); + // Call under ordinary refcount state to cover the non-overflow return path. + inner.inc_strong(); + // Revert the temporary increment so drop logic remains balanced. + inner.dec_strong(); + let _ = rc; + } + }; + } + + macro_rules! gen_inc_strong_non_overflow_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + // Build an unsized Rc<[T]> from a nondet vector. + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let inner = rc.inner(); + // Same branch target as sized: ordinary increment without overflow. + inner.inc_strong(); + // Keep the strong count balanced for teardown. + inner.dec_strong(); + let _ = rc; + } + }; + } + + macro_rules! gen_inc_strong_non_overflow_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + // Create `Rc` through coercion from a concrete source type. + let rc_src: Rc<$src_ty, Global> = Rc::new_in(kani::any::<$src_ty>(), Global); + let rc: Rc = rc_src; + let inner = rc.inner(); + // Call under normal non-overflow state. + inner.inc_strong(); + // Restore count immediately to avoid leaking one strong reference. + inner.dec_strong(); + let _ = rc; + } + }; + } + + #[kani::proof] + #[kani::should_panic] + pub fn harness_inc_strong_overflow_should_panic() { + // Start from a valid allocation, then force the pre-state for overflow branch. + let rc: Rc = Rc::new_in(kani::any::(), Global); + let inner = rc.inner(); + // Force `strong == usize::MAX`, so `wrapping_add(1)` becomes 0. + inner.strong_ref().set(usize::MAX); + // This must hit the overflow check and abort. + inner.inc_strong(); + // If execution reaches here, overflow branch was not taken as expected. + core::mem::forget(rc); + } + + gen_inc_strong_non_overflow_harness!(harness_inc_strong_i8, i8); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_i16, i16); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_i32, i32); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_i64, i64); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_i128, i128); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_u8, u8); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_u16, u16); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_u32, u32); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_u64, u64); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_u128, u128); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_unit, ()); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_array, [u8; 4]); + gen_inc_strong_non_overflow_harness!(harness_inc_strong_bool, bool); + gen_inc_strong_non_overflow_dyn_any_harness!(harness_inc_strong_dyn_any, i32); + + gen_inc_strong_non_overflow_unsized_harness!(harness_inc_strong_vec_u8, u8); + gen_inc_strong_non_overflow_unsized_harness!(harness_inc_strong_vec_u16, u16); + gen_inc_strong_non_overflow_unsized_harness!(harness_inc_strong_vec_u32, u32); + gen_inc_strong_non_overflow_unsized_harness!(harness_inc_strong_vec_u64, u64); + gen_inc_strong_non_overflow_unsized_harness!(harness_inc_strong_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3962 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `inc_weak` has two behavior paths controlled by the post-increment value: + // 1) non-overflow path: `weak.wrapping_add(1) != 0`, function returns normally; + // 2) overflow path: `weak.wrapping_add(1) == 0`, function aborts. + // + // Trigger conditions: + // - Path (1): call `inc_weak` from a regular live allocation, where weak starts from a + // valid non-zero count. + // - Path (2): force `weak == usize::MAX` immediately before calling `inc_weak`. + // + // Coverage in this module: + // - `*_non_overflow` harnesses cover path (1) for sized, unsized, and `dyn Any`. + // - `harness_inc_weak_overflow_should_panic` covers path (2). + macro_rules! gen_inc_weak_non_overflow_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + // Build a live `Rc` so the precondition `weak != 0` holds. + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let inner = rc.inner(); + // Trigger path (1): ordinary increment that does not wrap to zero. + inner.inc_weak(); + // Balance the temporary increment to keep teardown behavior stable. + inner.dec_weak(); + let _ = rc; + } + }; + } + + macro_rules! gen_inc_weak_non_overflow_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + // Build `Rc<[T]>` from nondeterministic vector input. + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let inner = rc.inner(); + // Trigger path (1) on an unsized payload. + inner.inc_weak(); + // Restore the weak count. + inner.dec_weak(); + let _ = rc; + } + }; + } + + macro_rules! gen_inc_weak_non_overflow_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + // Build trait object `Rc` from a concrete source type. + let rc_src: Rc<$src_ty, Global> = Rc::new_in(kani::any::<$src_ty>(), Global); + let rc: Rc = rc_src; + let inner = rc.inner(); + // Trigger path (1) in the same way as sized values. + inner.inc_weak(); + // Restore weak count immediately. + inner.dec_weak(); + let _ = rc; + } + }; + } + + #[kani::proof] + #[kani::should_panic] + pub fn harness_inc_weak_overflow_should_panic() { + // Start from a valid allocation and force overflow pre-state. + let rc: Rc = Rc::new_in(kani::any::(), Global); + let inner = rc.inner(); + // Force `weak == usize::MAX` so `wrapping_add(1)` becomes zero. + inner.weak_ref().set(usize::MAX); + // Trigger path (2): overflow should abort. + inner.inc_weak(); + // Avoid dropping forged state if panic handling changes. + core::mem::forget(rc); + } + + gen_inc_weak_non_overflow_harness!(harness_inc_weak_i8, i8); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_i16, i16); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_i32, i32); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_i64, i64); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_i128, i128); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_u8, u8); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_u16, u16); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_u32, u32); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_u64, u64); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_u128, u128); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_unit, ()); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_array, [u8; 4]); + gen_inc_weak_non_overflow_harness!(harness_inc_weak_bool, bool); + gen_inc_weak_non_overflow_dyn_any_harness!(harness_inc_weak_dyn_any, i32); + + gen_inc_weak_non_overflow_unsized_harness!(harness_inc_weak_vec_u8, u8); + gen_inc_weak_non_overflow_unsized_harness!(harness_inc_weak_vec_u16, u16); + gen_inc_weak_non_overflow_unsized_harness!(harness_inc_weak_vec_u32, u32); + gen_inc_weak_non_overflow_unsized_harness!(harness_inc_weak_vec_u64, u64); + gen_inc_weak_non_overflow_unsized_harness!(harness_inc_weak_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4403 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_uniquerc_into_rc_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let unique: UniqueRc<$ty, Global> = UniqueRc::new_in(kani::any::<$ty>(), Global); + let _rc: Rc<$ty, Global> = UniqueRc::into_rc(unique); + } + }; + } + + macro_rules! gen_uniquerc_into_rc_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + let unique_src: UniqueRc<$src_ty, Global> = + UniqueRc::new_in(kani::any::<$src_ty>(), Global); + let unique_dyn: UniqueRc = unique_src; + let _rc: Rc = UniqueRc::into_rc(unique_dyn); + } + }; + } + + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_i8, i8); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_i16, i16); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_i32, i32); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_i64, i64); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_i128, i128); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_u8, u8); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_u16, u16); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_u32, u32); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_u64, u64); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_u128, u128); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_bool, bool); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_unit, ()); + gen_uniquerc_into_rc_harness!(harness_uniquerc_into_rc_array, [u8; 4]); + gen_uniquerc_into_rc_dyn_any_harness!(harness_uniquerc_into_rc_dyn_any, i32); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4426 { + use core::any::Any; + + use super::*; + + macro_rules! gen_downgrade_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let unique: UniqueRc<$ty, Global> = UniqueRc::new_in(kani::any::<$ty>(), Global); + let _weak: Weak<$ty, Global> = UniqueRc::downgrade(&unique); + } + }; + } + + macro_rules! gen_downgrade_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + let unique_src: UniqueRc<$src_ty, Global> = + UniqueRc::new_in(kani::any::<$src_ty>(), Global); + let unique_dyn: UniqueRc = unique_src; + let _weak: Weak = UniqueRc::downgrade(&unique_dyn); + } + }; + } + + gen_downgrade_harness!(harness_downgrade_i8, i8); + gen_downgrade_harness!(harness_downgrade_i16, i16); + gen_downgrade_harness!(harness_downgrade_i32, i32); + gen_downgrade_harness!(harness_downgrade_i64, i64); + gen_downgrade_harness!(harness_downgrade_i128, i128); + gen_downgrade_harness!(harness_downgrade_u8, u8); + gen_downgrade_harness!(harness_downgrade_u16, u16); + gen_downgrade_harness!(harness_downgrade_u32, u32); + gen_downgrade_harness!(harness_downgrade_u64, u64); + gen_downgrade_harness!(harness_downgrade_u128, u128); + gen_downgrade_harness!(harness_downgrade_unit, ()); + gen_downgrade_harness!(harness_downgrade_array, [u8; 4]); + gen_downgrade_harness!(harness_downgrade_bool, bool); + gen_downgrade_dyn_any_harness!(harness_downgrade_dyn_any, i32); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4451 { + use core::any::Any; + + use super::*; + + macro_rules! gen_deref_mut_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let mut unique: UniqueRc<$ty, Global> = + UniqueRc::new_in(kani::any::<$ty>(), Global); + let _: &mut $ty = core::ops::DerefMut::deref_mut(&mut unique); + } + }; + } + + macro_rules! gen_deref_mut_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + let unique_src: UniqueRc<$src_ty, Global> = + UniqueRc::new_in(kani::any::<$src_ty>(), Global); + let mut unique_dyn: UniqueRc = unique_src; + let _: &mut dyn Any = core::ops::DerefMut::deref_mut(&mut unique_dyn); + } + }; + } + + gen_deref_mut_harness!(harness_deref_mut_i8, i8); + gen_deref_mut_harness!(harness_deref_mut_i16, i16); + gen_deref_mut_harness!(harness_deref_mut_i32, i32); + gen_deref_mut_harness!(harness_deref_mut_i64, i64); + gen_deref_mut_harness!(harness_deref_mut_i128, i128); + gen_deref_mut_harness!(harness_deref_mut_u8, u8); + gen_deref_mut_harness!(harness_deref_mut_u16, u16); + gen_deref_mut_harness!(harness_deref_mut_u32, u32); + gen_deref_mut_harness!(harness_deref_mut_u64, u64); + gen_deref_mut_harness!(harness_deref_mut_u128, u128); + gen_deref_mut_harness!(harness_deref_mut_bool, bool); + gen_deref_mut_harness!(harness_deref_mut_unit, ()); + gen_deref_mut_harness!(harness_deref_mut_array, [u8; 4]); + gen_deref_mut_dyn_any_harness!(harness_deref_mut_dyn_any, i32); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4443 { + use core::any::Any; + + use super::*; + + macro_rules! gen_deref_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let unique: UniqueRc<$ty, Global> = UniqueRc::new_in(kani::any::<$ty>(), Global); + let _: &$ty = core::ops::Deref::deref(&unique); + } + }; + } + + macro_rules! gen_deref_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + let unique_src: UniqueRc<$src_ty, Global> = + UniqueRc::new_in(kani::any::<$src_ty>(), Global); + let unique_dyn: UniqueRc = unique_src; + let _: &dyn Any = core::ops::Deref::deref(&unique_dyn); + } + }; + } + + gen_deref_harness!(harness_deref_i8, i8); + gen_deref_harness!(harness_deref_i16, i16); + gen_deref_harness!(harness_deref_i32, i32); + gen_deref_harness!(harness_deref_i64, i64); + gen_deref_harness!(harness_deref_i128, i128); + gen_deref_harness!(harness_deref_u8, u8); + gen_deref_harness!(harness_deref_u16, u16); + gen_deref_harness!(harness_deref_u32, u32); + gen_deref_harness!(harness_deref_u64, u64); + gen_deref_harness!(harness_deref_u128, u128); + gen_deref_harness!(harness_deref_bool, bool); + gen_deref_harness!(harness_deref_unit, ()); + gen_deref_harness!(harness_deref_array, [u8; 4]); + gen_deref_dyn_any_harness!(harness_deref_dyn_any, i32); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4461 { + use core::any::Any; + + use super::*; + + // `UniqueRc::drop` has one branch that matters for allocator deallocation: + // - after dropping value and calling `dec_weak()`, + // * `weak() == 0` => deallocate backing allocation in this `drop`; + // * `weak() != 0` => do not deallocate here (remaining `Weak` owns cleanup). + // + // We cover both paths for each type: + // 1) `*_unique`: no external weak created, so after implicit weak decrement we hit `weak()==0`. + // 2) `*_weak_present`: create one `Weak` before dropping UniqueRc, so after decrement `weak()>0`. + macro_rules! gen_drop_unique_rc_harness { + ($unique:ident, $weak_present:ident, $ty:ty) => { + #[kani::proof] + pub fn $unique() { + // No external weak: dropping `unique` should follow the `weak()==0` branch. + let _unique: UniqueRc<$ty, Global> = UniqueRc::new_in(kani::any::<$ty>(), Global); + } + + #[kani::proof] + pub fn $weak_present() { + // Create one external weak first, so `UniqueRc::drop` observes remaining weak refs. + let unique: UniqueRc<$ty, Global> = UniqueRc::new_in(kani::any::<$ty>(), Global); + let weak: Weak<$ty, Global> = UniqueRc::downgrade(&unique); + { + // Drop strong owner now; `UniqueRc::drop` takes the `weak()!=0` branch. + let _dropped_strong = unique; + } + // Keep weak alive across the strong drop to preserve the branch condition. + let _ = weak; + } + }; + } + + macro_rules! gen_drop_unique_rc_dyn_any_harness { + ($unique:ident, $weak_present:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $unique() { + // Build `UniqueRc` from a concrete source type and drop directly. + let unique_src: UniqueRc<$src_ty, Global> = + UniqueRc::new_in(kani::any::<$src_ty>(), Global); + let _unique_dyn: UniqueRc = unique_src; + } + + #[kani::proof] + pub fn $weak_present() { + // Build trait object, create weak alias, then drop strong owner. + let unique_src: UniqueRc<$src_ty, Global> = + UniqueRc::new_in(kani::any::<$src_ty>(), Global); + let unique_dyn: UniqueRc = unique_src; + let weak: Weak = UniqueRc::downgrade(&unique_dyn); + { + let _dropped_strong = unique_dyn; + } + let _ = weak; + } + }; + } + + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_i8_unique, + harness_drop_unique_rc_i8_weak_present, + i8 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_i16_unique, + harness_drop_unique_rc_i16_weak_present, + i16 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_i32_unique, + harness_drop_unique_rc_i32_weak_present, + i32 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_i64_unique, + harness_drop_unique_rc_i64_weak_present, + i64 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_i128_unique, + harness_drop_unique_rc_i128_weak_present, + i128 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_u8_unique, + harness_drop_unique_rc_u8_weak_present, + u8 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_u16_unique, + harness_drop_unique_rc_u16_weak_present, + u16 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_u32_unique, + harness_drop_unique_rc_u32_weak_present, + u32 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_u64_unique, + harness_drop_unique_rc_u64_weak_present, + u64 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_u128_unique, + harness_drop_unique_rc_u128_weak_present, + u128 + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_unit_unique, + harness_drop_unique_rc_unit_weak_present, + () + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_array_unique, + harness_drop_unique_rc_array_weak_present, + [u8; 4] + ); + gen_drop_unique_rc_harness!( + harness_drop_unique_rc_bool_unique, + harness_drop_unique_rc_bool_weak_present, + bool + ); + gen_drop_unique_rc_dyn_any_harness!( + harness_drop_unique_rc_dyn_any_unique, + harness_drop_unique_rc_dyn_any_weak_present, + i32 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4493 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_unique_rc_uninit_new_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $ty = kani::any::<$ty>(); + let for_value: &$ty = &value; + let _uninit: UniqueRcUninit<$ty, Global> = UniqueRcUninit::new(for_value, Global); + } + }; + } + + macro_rules! gen_unique_rc_uninit_new_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $src_ty = kani::any::<$src_ty>(); + let trait_obj: &dyn Any = &value; + let _uninit: UniqueRcUninit = + UniqueRcUninit::new(trait_obj, Global); + } + }; + } + + macro_rules! gen_unique_rc_uninit_new_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let slice: &[$elem] = nondet_rc_slice(&vec); + let _uninit: UniqueRcUninit<[$elem], Global> = UniqueRcUninit::new(slice, Global); + } + }; + } + + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_i8, i8); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_i16, i16); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_i32, i32); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_i64, i64); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_i128, i128); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_u8, u8); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_u16, u16); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_u32, u32); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_u64, u64); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_u128, u128); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_unit, ()); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_array, [u8; 4]); + gen_unique_rc_uninit_new_harness!(harness_unique_rc_uninit_new_bool, bool); + gen_unique_rc_uninit_new_dyn_any_harness!(harness_unique_rc_uninit_new_dyn_any, i32); + + gen_unique_rc_uninit_new_unsized_harness!(harness_unique_rc_uninit_new_slice_u8, u8); + gen_unique_rc_uninit_new_unsized_harness!(harness_unique_rc_uninit_new_slice_u16, u16); + gen_unique_rc_uninit_new_unsized_harness!(harness_unique_rc_uninit_new_slice_u32, u32); + gen_unique_rc_uninit_new_unsized_harness!(harness_unique_rc_uninit_new_slice_u64, u64); + gen_unique_rc_uninit_new_unsized_harness!(harness_unique_rc_uninit_new_slice_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4510 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_data_ptr_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $ty = kani::any::<$ty>(); + let mut uninit: UniqueRcUninit<$ty, Global> = UniqueRcUninit::new(&value, Global); + let _ptr: *mut $ty = uninit.data_ptr(); + } + }; + } + + macro_rules! gen_data_ptr_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $src_ty = kani::any::<$src_ty>(); + let trait_obj: &dyn Any = &value; + let mut uninit: UniqueRcUninit = + UniqueRcUninit::new(trait_obj, Global); + let _ptr: *mut dyn Any = uninit.data_ptr(); + } + }; + } + + macro_rules! gen_data_ptr_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec::<$elem>(); + let slice = nondet_rc_slice(&vec); + let mut uninit: UniqueRcUninit<[$elem], Global> = + UniqueRcUninit::new(slice, Global); + let _ptr: *mut [$elem] = uninit.data_ptr(); + } + }; + } + + gen_data_ptr_harness!(harness_data_ptr_i8, i8); + gen_data_ptr_harness!(harness_data_ptr_i16, i16); + gen_data_ptr_harness!(harness_data_ptr_i32, i32); + gen_data_ptr_harness!(harness_data_ptr_i64, i64); + gen_data_ptr_harness!(harness_data_ptr_i128, i128); + gen_data_ptr_harness!(harness_data_ptr_u8, u8); + gen_data_ptr_harness!(harness_data_ptr_u16, u16); + gen_data_ptr_harness!(harness_data_ptr_u32, u32); + gen_data_ptr_harness!(harness_data_ptr_u64, u64); + gen_data_ptr_harness!(harness_data_ptr_u128, u128); + gen_data_ptr_harness!(harness_data_ptr_unit, ()); + gen_data_ptr_harness!(harness_data_ptr_array, [u8; 4]); + gen_data_ptr_harness!(harness_data_ptr_bool, bool); + gen_data_ptr_dyn_any_harness!(harness_data_ptr_dyn_any, i32); + + gen_data_ptr_unsized_harness!(harness_data_ptr_slice_u8, u8); + gen_data_ptr_unsized_harness!(harness_data_ptr_slice_u16, u16); + gen_data_ptr_unsized_harness!(harness_data_ptr_slice_u32, u32); + gen_data_ptr_unsized_harness!(harness_data_ptr_slice_u64, u64); + gen_data_ptr_unsized_harness!(harness_data_ptr_slice_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_4533 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_unique_rc_uninit_drop_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $ty = kani::any::<$ty>(); + let _uninit: UniqueRcUninit<$ty, Global> = UniqueRcUninit::new(&value, Global); + } + }; + } + + macro_rules! gen_unique_rc_uninit_drop_dyn_any_harness { + ($name:ident, $src_ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $src_ty = kani::any::<$src_ty>(); + let trait_obj: &dyn Any = &value; + let _uninit: UniqueRcUninit = + UniqueRcUninit::new(trait_obj, Global); + } + }; + } + + macro_rules! gen_unique_rc_uninit_drop_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec::<$elem>(); + let slice = nondet_rc_slice(&vec); + let _uninit: UniqueRcUninit<[$elem], Global> = UniqueRcUninit::new(slice, Global); + } + }; + } + + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_i8, i8); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_i16, i16); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_i32, i32); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_i64, i64); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_i128, i128); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_u8, u8); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_u16, u16); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_u32, u32); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_u64, u64); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_u128, u128); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_unit, ()); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_array, [u8; 4]); + gen_unique_rc_uninit_drop_harness!(harness_unique_rc_uninit_drop_bool, bool); + gen_unique_rc_uninit_drop_dyn_any_harness!(harness_unique_rc_uninit_drop_dyn_any, i32); + + gen_unique_rc_uninit_drop_unsized_harness!(harness_unique_rc_uninit_drop_slice_u8, u8); + gen_unique_rc_uninit_drop_unsized_harness!(harness_unique_rc_uninit_drop_slice_u16, u16); + gen_unique_rc_uninit_drop_unsized_harness!(harness_unique_rc_uninit_drop_slice_u32, u32); + gen_unique_rc_uninit_drop_unsized_harness!(harness_unique_rc_uninit_drop_slice_u64, u64); + gen_unique_rc_uninit_drop_unsized_harness!(harness_unique_rc_uninit_drop_slice_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_368 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_inner_sized_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _ = rc.inner(); + } + }; + } + + macro_rules! gen_inner_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let _ = rc.inner(); + } + }; + } + + gen_inner_sized_harness!(harness_inner_i8, i8); + gen_inner_sized_harness!(harness_inner_i16, i16); + gen_inner_sized_harness!(harness_inner_i32, i32); + gen_inner_sized_harness!(harness_inner_i64, i64); + gen_inner_sized_harness!(harness_inner_i128, i128); + gen_inner_sized_harness!(harness_inner_u8, u8); + gen_inner_sized_harness!(harness_inner_u16, u16); + gen_inner_sized_harness!(harness_inner_u32, u32); + gen_inner_sized_harness!(harness_inner_u64, u64); + gen_inner_sized_harness!(harness_inner_u128, u128); + gen_inner_sized_harness!(harness_inner_unit, ()); + gen_inner_sized_harness!(harness_inner_array, [u8; 4]); + gen_inner_sized_harness!(harness_inner_bool, bool); + + gen_inner_unsized_harness!(harness_inner_vec_u8, u8); + gen_inner_unsized_harness!(harness_inner_vec_u16, u16); + gen_inner_unsized_harness!(harness_inner_vec_u32, u32); + gen_inner_unsized_harness!(harness_inner_vec_u64, u64); + gen_inner_unsized_harness!(harness_inner_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_375 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_into_inner_with_allocator_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let (ptr, alloc) = Rc::<$ty, Global>::into_inner_with_allocator(rc); + let _recovered: Rc<$ty, Global> = + unsafe { Rc::<$ty, Global>::from_inner_in(ptr, alloc) }; + } + }; + } + + macro_rules! gen_into_inner_with_allocator_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let (ptr, alloc) = Rc::<[$elem], Global>::into_inner_with_allocator(rc); + let _recovered: Rc<[$elem], Global> = + unsafe { Rc::<[$elem], Global>::from_inner_in(ptr, alloc) }; + } + }; + } + + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_i8, i8); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_i16, i16); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_i32, i32); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_i64, i64); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_i128, i128); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_u8, u8); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_u16, u16); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_u32, u32); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_u64, u64); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_u128, u128); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_unit, ()); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_array, [u8; 4]); + gen_into_inner_with_allocator_harness!(harness_into_inner_with_allocator_bool, bool); + + gen_into_inner_with_allocator_unsized_harness!(harness_into_inner_with_allocator_vec_u8, u8); + gen_into_inner_with_allocator_unsized_harness!(harness_into_inner_with_allocator_vec_u16, u16); + gen_into_inner_with_allocator_unsized_harness!(harness_into_inner_with_allocator_vec_u32, u32); + gen_into_inner_with_allocator_unsized_harness!(harness_into_inner_with_allocator_vec_u64, u64); + gen_into_inner_with_allocator_unsized_harness!(harness_into_inner_with_allocator_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_425 { + use super::*; + + macro_rules! gen_rc_new_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $ty = kani::any::<$ty>(); + let _rc: Rc<$ty> = Rc::new(value); + } + }; + } + + gen_rc_new_harness!(harness_rc_new_i8, i8); + gen_rc_new_harness!(harness_rc_new_i16, i16); + gen_rc_new_harness!(harness_rc_new_i32, i32); + gen_rc_new_harness!(harness_rc_new_i64, i64); + gen_rc_new_harness!(harness_rc_new_i128, i128); + gen_rc_new_harness!(harness_rc_new_u8, u8); + gen_rc_new_harness!(harness_rc_new_u16, u16); + gen_rc_new_harness!(harness_rc_new_u32, u32); + gen_rc_new_harness!(harness_rc_new_u64, u64); + gen_rc_new_harness!(harness_rc_new_u128, u128); + gen_rc_new_harness!(harness_rc_new_unit, ()); + gen_rc_new_harness!(harness_rc_new_array_u8_4, [u8; 4]); + gen_rc_new_harness!(harness_rc_new_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_521 { + use super::*; + + macro_rules! gen_rc_new_uninit_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _rc: Rc> = Rc::<$ty>::new_uninit(); + } + }; + } + + gen_rc_new_uninit_harness!(harness_rc_new_uninit_i8, i8); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_i16, i16); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_i32, i32); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_i64, i64); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_i128, i128); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_u8, u8); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_u16, u16); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_u32, u32); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_u64, u64); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_u128, u128); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_unit, ()); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_array, [u8; 4]); + gen_rc_new_uninit_harness!(harness_rc_new_uninit_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_552 { + use super::*; + + macro_rules! gen_rc_new_zeroed_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _rc: Rc> = Rc::<$ty>::new_zeroed(); + } + }; + } + + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_i8, i8); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_i16, i16); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_i32, i32); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_i64, i64); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_i128, i128); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_u8, u8); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_u16, u16); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_u32, u32); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_u64, u64); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_u128, u128); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_unit, ()); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_array, [u8; 4]); + gen_rc_new_zeroed_harness!(harness_rc_new_zeroed_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_711 { + use super::*; + + macro_rules! gen_new_uninit_in_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _rc: Rc, Global> = + Rc::<$ty, Global>::new_uninit_in(Global); + } + }; + } + + gen_new_uninit_in_harness!(harness_new_uninit_in_i8, i8); + gen_new_uninit_in_harness!(harness_new_uninit_in_i16, i16); + gen_new_uninit_in_harness!(harness_new_uninit_in_i32, i32); + gen_new_uninit_in_harness!(harness_new_uninit_in_i64, i64); + gen_new_uninit_in_harness!(harness_new_uninit_in_i128, i128); + gen_new_uninit_in_harness!(harness_new_uninit_in_u8, u8); + gen_new_uninit_in_harness!(harness_new_uninit_in_u16, u16); + gen_new_uninit_in_harness!(harness_new_uninit_in_u32, u32); + gen_new_uninit_in_harness!(harness_new_uninit_in_u64, u64); + gen_new_uninit_in_harness!(harness_new_uninit_in_u128, u128); + gen_new_uninit_in_harness!(harness_new_uninit_in_unit, ()); + gen_new_uninit_in_harness!(harness_new_uninit_in_array, [u8; 4]); + gen_new_uninit_in_harness!(harness_new_uninit_in_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_748 { + use super::*; + + macro_rules! gen_new_zeroed_in_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _rc: Rc, Global> = + Rc::<$ty, Global>::new_zeroed_in(Global); + } + }; + } + + gen_new_zeroed_in_harness!(harness_new_zeroed_in_i8, i8); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_i16, i16); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_i32, i32); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_i64, i64); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_i128, i128); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_u8, u8); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_u16, u16); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_u32, u32); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_u64, u64); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_u128, u128); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_unit, ()); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_array, [u8; 4]); + gen_new_zeroed_in_harness!(harness_new_zeroed_in_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_792 { + use super::*; + + macro_rules! gen_new_cyclic_in_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _rc: Rc<$ty, Global> = Rc::<$ty, Global>::new_cyclic_in( + |weak: &Weak<$ty, Global>| { + let _ = weak.upgrade(); + kani::any::<$ty>() + }, + Global, + ); + } + }; + } + + gen_new_cyclic_in_harness!(harness_new_cyclic_in_i8, i8); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_i16, i16); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_i32, i32); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_i64, i64); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_i128, i128); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_u8, u8); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_u16, u16); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_u32, u32); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_u64, u64); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_u128, u128); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_unit, ()); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_array, [u8; 4]); + gen_new_cyclic_in_harness!(harness_new_cyclic_in_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_857 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_try_new_in_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _result = Rc::<$ty, Global>::try_new_in(kani::any::<$ty>(), Global); + } + }; + } + + macro_rules! gen_try_new_in_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec::<$elem>(); + let _result = Rc::, Global>::try_new_in(vec, Global); + } + }; + } + + gen_try_new_in_harness!(harness_try_new_in_i8, i8); + gen_try_new_in_harness!(harness_try_new_in_i16, i16); + gen_try_new_in_harness!(harness_try_new_in_i32, i32); + gen_try_new_in_harness!(harness_try_new_in_i64, i64); + gen_try_new_in_harness!(harness_try_new_in_i128, i128); + gen_try_new_in_harness!(harness_try_new_in_u8, u8); + gen_try_new_in_harness!(harness_try_new_in_u16, u16); + gen_try_new_in_harness!(harness_try_new_in_u32, u32); + gen_try_new_in_harness!(harness_try_new_in_u64, u64); + gen_try_new_in_harness!(harness_try_new_in_u128, u128); + gen_try_new_in_harness!(harness_try_new_in_unit, ()); + gen_try_new_in_harness!(harness_try_new_in_array, [u8; 4]); + gen_try_new_in_harness!(harness_try_new_in_bool, bool); + + gen_try_new_in_unsized_harness!(harness_try_new_in_vec_u8, u8); + gen_try_new_in_unsized_harness!(harness_try_new_in_vec_u16, u16); + gen_try_new_in_unsized_harness!(harness_try_new_in_vec_u32, u32); + gen_try_new_in_unsized_harness!(harness_try_new_in_vec_u64, u64); + gen_try_new_in_unsized_harness!(harness_try_new_in_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_899 { + use super::*; + + macro_rules! gen_try_new_uninit_in_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _result = Rc::<$ty, Global>::try_new_uninit_in(Global); + } + }; + } + + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_i8, i8); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_i16, i16); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_i32, i32); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_i64, i64); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_i128, i128); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_u8, u8); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_u16, u16); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_u32, u32); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_u64, u64); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_u128, u128); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_unit, ()); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_array, [u8; 4]); + gen_try_new_uninit_in_harness!(harness_try_new_uninit_in_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_937 { + use super::*; + + macro_rules! gen_try_new_zeroed_in_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _result = Rc::<$ty, Global>::try_new_zeroed_in(Global); + } + }; + } + + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_i8, i8); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_i16, i16); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_i32, i32); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_i64, i64); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_i128, i128); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_u8, u8); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_u16, u16); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_u32, u32); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_u64, u64); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_u128, u128); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_unit, ()); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_array, [u8; 4]); + gen_try_new_zeroed_in_harness!(harness_try_new_zeroed_in_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_955 { + use core::marker::PhantomPinned; + + use super::*; + + struct NotUnpinSentinel(u8, PhantomPinned); + + macro_rules! gen_pin_in_harness { + ($name:ident, NotUnpinSentinel) => { + #[kani::proof] + pub fn $name() { + let value = NotUnpinSentinel(kani::any(), PhantomPinned); + let _pinned = Rc::::pin_in(value, Global); + } + }; + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _pinned = Rc::<$ty, Global>::pin_in(kani::any::<$ty>(), Global); + } + }; + } + + gen_pin_in_harness!(harness_pin_in_i8, i8); + gen_pin_in_harness!(harness_pin_in_i16, i16); + gen_pin_in_harness!(harness_pin_in_i32, i32); + gen_pin_in_harness!(harness_pin_in_i64, i64); + gen_pin_in_harness!(harness_pin_in_i128, i128); + gen_pin_in_harness!(harness_pin_in_u8, u8); + gen_pin_in_harness!(harness_pin_in_u16, u16); + gen_pin_in_harness!(harness_pin_in_u32, u32); + gen_pin_in_harness!(harness_pin_in_u64, u64); + gen_pin_in_harness!(harness_pin_in_u128, u128); + gen_pin_in_harness!(harness_pin_in_unit, ()); + gen_pin_in_harness!(harness_pin_in_array, [u8; 4]); + gen_pin_in_harness!(harness_pin_in_bool, bool); + gen_pin_in_harness!(harness_pin_in_not_unpin_sentinel, NotUnpinSentinel); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1065 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_new_uninit_slice_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let len = kani::any_where(|l: &usize| rc_slice_layout_ok::<$ty>(*l)); + let _rc: Rc<[mem::MaybeUninit<$ty>]> = Rc::<[$ty]>::new_uninit_slice(len); + } + }; + } + + gen_new_uninit_slice_harness!(harness_new_uninit_slice_i8, i8); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_i16, i16); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_i32, i32); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_i64, i64); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_i128, i128); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_u8, u8); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_u16, u16); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_u32, u32); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_u64, u64); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_u128, u128); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_unit, ()); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_bool, bool); + gen_new_uninit_slice_harness!(harness_new_uninit_slice_array, [u8; 4]); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1090 { + use super::*; + use crate::rc::kani_rc_harness_helpers::*; + + macro_rules! gen_new_zeroed_slice_harness { + ($name:ident, $elem_ty:ty) => { + #[kani::proof] + pub fn $name() { + let len = kani::any_where(|l: &usize| rc_slice_layout_ok::<$elem_ty>(*l)); + let _rc: Rc<[mem::MaybeUninit<$elem_ty>]> = Rc::<[$elem_ty]>::new_zeroed_slice(len); + } + }; + } + + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_i8, i8); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_i16, i16); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_i32, i32); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_i64, i64); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_i128, i128); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_u8, u8); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_u16, u16); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_u32, u32); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_u64, u64); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_u128, u128); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_unit, ()); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_bool, bool); + gen_new_zeroed_slice_harness!(harness_new_zeroed_slice_array, [u8; 4]); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1111 { + use super::*; + use crate::rc::kani_rc_harness_helpers::*; + + macro_rules! gen_into_array_slice_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$ty>(); + let rc: Rc<[$ty]> = Rc::from(vec); + const N: usize = 100; + let _: Option> = rc.into_array::(); + } + }; + } + + gen_into_array_slice_harness!(harness_into_array_slice_i8, i8); + gen_into_array_slice_harness!(harness_into_array_slice_i16, i16); + gen_into_array_slice_harness!(harness_into_array_slice_i32, i32); + gen_into_array_slice_harness!(harness_into_array_slice_i64, i64); + gen_into_array_slice_harness!(harness_into_array_slice_i128, i128); + gen_into_array_slice_harness!(harness_into_array_slice_u8, u8); + gen_into_array_slice_harness!(harness_into_array_slice_u16, u16); + gen_into_array_slice_harness!(harness_into_array_slice_u32, u32); + gen_into_array_slice_harness!(harness_into_array_slice_u64, u64); + gen_into_array_slice_harness!(harness_into_array_slice_u128, u128); + gen_into_array_slice_harness!(harness_into_array_slice_unit, ()); + gen_into_array_slice_harness!(harness_into_array_slice_bool, bool); + gen_into_array_slice_harness!(harness_into_array_slice_array, [u8; 4]); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_657 { + use core::marker::PhantomPinned; + + use super::*; + + struct NotUnpinSentinel(u8, PhantomPinned); + + macro_rules! gen_pin_harness { + ($name:ident, NotUnpinSentinel) => { + #[kani::proof] + pub fn $name() { + let value = NotUnpinSentinel(kani::any(), PhantomPinned); + let _pinned = Rc::pin(value); + } + }; + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let value: $ty = kani::any(); + let _pinned = Rc::pin(value); + } + }; + } + + gen_pin_harness!(harness_pin_i8, i8); + gen_pin_harness!(harness_pin_i16, i16); + gen_pin_harness!(harness_pin_i32, i32); + gen_pin_harness!(harness_pin_i64, i64); + gen_pin_harness!(harness_pin_i128, i128); + gen_pin_harness!(harness_pin_u8, u8); + gen_pin_harness!(harness_pin_u16, u16); + gen_pin_harness!(harness_pin_u32, u32); + gen_pin_harness!(harness_pin_u64, u64); + gen_pin_harness!(harness_pin_u128, u128); + gen_pin_harness!(harness_pin_unit, ()); + gen_pin_harness!(harness_pin_bool, bool); + gen_pin_harness!(harness_pin_array, [u8; 4]); + gen_pin_harness!(harness_pin_not_unpin_sentinel, NotUnpinSentinel); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1152 { + use super::*; + use crate::rc::kani_rc_harness_helpers::*; + + macro_rules! gen_new_uninit_slice_in_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let len = kani::any_where(|l: &usize| rc_slice_layout_ok::<$ty>(*l)); + let _rc: Rc<[mem::MaybeUninit<$ty>], Global> = + Rc::<[$ty]>::new_uninit_slice_in(len, Global); + } + }; + } + + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_i8, i8); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_i16, i16); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_i32, i32); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_i64, i64); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_i128, i128); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_u8, u8); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_u16, u16); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_u32, u32); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_u64, u64); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_u128, u128); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_unit, ()); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_bool, bool); + gen_new_uninit_slice_in_harness!(harness_new_uninit_slice_in_array, [u8; 4]); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_574 { + use super::*; + use crate::rc::kani_rc_harness_helpers::*; + + macro_rules! gen_try_new_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _result = Rc::<$ty>::try_new(kani::any::<$ty>()); + } + }; + } + + macro_rules! gen_try_new_vec_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec::<$elem>(); + let _ = Rc::>::try_new(vec); + } + }; + } + + gen_try_new_harness!(harness_try_new_i8, i8); + gen_try_new_harness!(harness_try_new_i16, i16); + gen_try_new_harness!(harness_try_new_i32, i32); + gen_try_new_harness!(harness_try_new_i64, i64); + gen_try_new_harness!(harness_try_new_i128, i128); + gen_try_new_harness!(harness_try_new_u8, u8); + gen_try_new_harness!(harness_try_new_u16, u16); + gen_try_new_harness!(harness_try_new_u32, u32); + gen_try_new_harness!(harness_try_new_u64, u64); + gen_try_new_harness!(harness_try_new_u128, u128); + gen_try_new_harness!(harness_try_new_unit, ()); + gen_try_new_harness!(harness_try_new_bool, bool); + gen_try_new_harness!(harness_try_new_array, [u8; 4]); + + gen_try_new_vec_harness!(harness_try_new_vec_u8, u8); + gen_try_new_vec_harness!(harness_try_new_vec_u16, u16); + gen_try_new_vec_harness!(harness_try_new_vec_u32, u32); + gen_try_new_vec_harness!(harness_try_new_vec_u64, u64); + gen_try_new_vec_harness!(harness_try_new_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_611 { + use super::*; + + macro_rules! gen_try_new_uninit_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _result = Rc::<$ty>::try_new_uninit(); + } + }; + } + + gen_try_new_uninit_harness!(harness_try_new_uninit_i8, i8); + gen_try_new_uninit_harness!(harness_try_new_uninit_i16, i16); + gen_try_new_uninit_harness!(harness_try_new_uninit_i32, i32); + gen_try_new_uninit_harness!(harness_try_new_uninit_i64, i64); + gen_try_new_uninit_harness!(harness_try_new_uninit_i128, i128); + gen_try_new_uninit_harness!(harness_try_new_uninit_u8, u8); + gen_try_new_uninit_harness!(harness_try_new_uninit_u16, u16); + gen_try_new_uninit_harness!(harness_try_new_uninit_u32, u32); + gen_try_new_uninit_harness!(harness_try_new_uninit_u64, u64); + gen_try_new_uninit_harness!(harness_try_new_uninit_u128, u128); + gen_try_new_uninit_harness!(harness_try_new_uninit_unit, ()); + gen_try_new_uninit_harness!(harness_try_new_uninit_array, [u8; 4]); + gen_try_new_uninit_harness!(harness_try_new_uninit_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_643 { + use super::*; + + macro_rules! gen_try_new_zeroed_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _result = Rc::<$ty>::try_new_zeroed(); + } + }; + } + + gen_try_new_zeroed_harness!(harness_try_new_zeroed_i8, i8); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_i16, i16); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_i32, i32); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_i64, i64); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_i128, i128); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_u8, u8); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_u16, u16); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_u32, u32); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_u64, u64); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_u128, u128); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_unit, ()); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_array, [u8; 4]); + gen_try_new_zeroed_harness!(harness_try_new_zeroed_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_983 { + use super::*; + use crate::rc::kani_rc_harness_helpers::*; + + // `Rc::try_unwrap` has two relevant runtime cases: + // - If the strong count is exactly 1, it returns `Ok(T)` and moves `T` out. + // - If there is more than one strong reference, it returns `Err(Rc)`. + // Weak references do not prevent the success path, so they should be covered separately. + // These harnesses exercise: + // 1) unique strong owner (success path), + // 2) shared strong owner (error path), + // 3) unique strong owner with outstanding weak refs (success-with-weak path). + macro_rules! gen_try_unwrap_harness { + ($unique:ident, $shared:ident, $weak_present:ident, $ty:ty) => { + gen_try_unwrap_harness!($unique, $shared, $weak_present, $ty, kani::any::<$ty>()); + }; + ($unique:ident, $shared:ident, $weak_present:ident, $ty:ty, $expr:expr) => { + #[kani::proof] + pub fn $unique() { + let rc: Rc<$ty, Global> = Rc::new_in($expr, Global); + let _ = Rc::<$ty, Global>::try_unwrap(rc); + } + + #[kani::proof] + pub fn $shared() { + let rc: Rc<$ty, Global> = Rc::new_in($expr, Global); + let _shared = Rc::clone(&rc); + let _ = Rc::<$ty, Global>::try_unwrap(rc); + } + + #[kani::proof] + pub fn $weak_present() { + let rc: Rc<$ty, Global> = Rc::new_in($expr, Global); + let _weak = Rc::downgrade(&rc); + let _ = Rc::<$ty, Global>::try_unwrap(rc); + } + }; + } + + macro_rules! gen_try_unwrap_vec_harness { + ($unique:ident, $shared:ident, $weak_present:ident, $elem:ty) => { + gen_try_unwrap_harness!( + $unique, + $shared, + $weak_present, + Vec<$elem>, + verifier_nondet_vec::<$elem>() + ); + }; + } + + gen_try_unwrap_harness!( + harness_try_unwrap_i8_unique, + harness_try_unwrap_i8_shared, + harness_try_unwrap_i8_weak_present, + i8 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_i16_unique, + harness_try_unwrap_i16_shared, + harness_try_unwrap_i16_weak_present, + i16 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_i32_unique, + harness_try_unwrap_i32_shared, + harness_try_unwrap_i32_weak_present, + i32 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_i64_unique, + harness_try_unwrap_i64_shared, + harness_try_unwrap_i64_weak_present, + i64 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_i128_unique, + harness_try_unwrap_i128_shared, + harness_try_unwrap_i128_weak_present, + i128 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_u8_unique, + harness_try_unwrap_u8_shared, + harness_try_unwrap_u8_weak_present, + u8 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_u16_unique, + harness_try_unwrap_u16_shared, + harness_try_unwrap_u16_weak_present, + u16 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_u32_unique, + harness_try_unwrap_u32_shared, + harness_try_unwrap_u32_weak_present, + u32 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_u64_unique, + harness_try_unwrap_u64_shared, + harness_try_unwrap_u64_weak_present, + u64 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_u128_unique, + harness_try_unwrap_u128_shared, + harness_try_unwrap_u128_weak_present, + u128 + ); + gen_try_unwrap_harness!( + harness_try_unwrap_unit_unique, + harness_try_unwrap_unit_shared, + harness_try_unwrap_unit_weak_present, + () + ); + gen_try_unwrap_harness!( + harness_try_unwrap_array_unique, + harness_try_unwrap_array_shared, + harness_try_unwrap_array_weak_present, + [u8; 4] + ); + gen_try_unwrap_harness!( + harness_try_unwrap_bool_unique, + harness_try_unwrap_bool_shared, + harness_try_unwrap_bool_weak_present, + bool + ); + + gen_try_unwrap_vec_harness!( + harness_try_unwrap_vec_u8_unique, + harness_try_unwrap_vec_u8_shared, + harness_try_unwrap_vec_u8_weak_present, + u8 + ); + gen_try_unwrap_vec_harness!( + harness_try_unwrap_vec_u16_unique, + harness_try_unwrap_vec_u16_shared, + harness_try_unwrap_vec_u16_weak_present, + u16 + ); + gen_try_unwrap_vec_harness!( + harness_try_unwrap_vec_u32_unique, + harness_try_unwrap_vec_u32_shared, + harness_try_unwrap_vec_u32_weak_present, + u32 + ); + gen_try_unwrap_vec_harness!( + harness_try_unwrap_vec_u64_unique, + harness_try_unwrap_vec_u64_shared, + harness_try_unwrap_vec_u64_weak_present, + u64 + ); + gen_try_unwrap_vec_harness!( + harness_try_unwrap_vec_u128_unique, + harness_try_unwrap_vec_u128_shared, + harness_try_unwrap_vec_u128_weak_present, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1180 { + use super::*; + use crate::rc::kani_rc_harness_helpers::*; + + macro_rules! gen_new_zeroed_slice_in_harness { + ($name:ident, $elem_ty:ty) => { + #[kani::proof] + pub fn $name() { + type T = $elem_ty; + let len = kani::any_where(|l: &usize| rc_slice_layout_ok::(*l)); + let _rc: Rc<[mem::MaybeUninit], Global> = + Rc::<[T]>::new_zeroed_slice_in(len, Global); + } + }; + } + + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_i8, i8); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_i16, i16); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_i32, i32); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_i64, i64); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_i128, i128); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_u8, u8); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_u16, u16); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_u32, u32); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_u64, u64); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_u128, u128); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_unit, ()); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_bool, bool); + gen_new_zeroed_slice_in_harness!(harness_new_zeroed_slice_in_array, [u8; 4]); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1580 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_as_ptr_harness { + ($name:ident, dyn Any) => { + #[kani::proof] + pub fn $name() { + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let rc: Rc = rc_i32; + let rc_clone: Rc = Rc::clone(&rc); + let _ptr = Rc::::as_ptr(&rc); + let _clone_ptr = Rc::::as_ptr(&rc_clone); + } + }; + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let rc_clone: Rc<$ty, Global> = Rc::clone(&rc); + let _ptr = Rc::<$ty, Global>::as_ptr(&rc); + let _clone_ptr = Rc::<$ty, Global>::as_ptr(&rc_clone); + } + }; + } + + macro_rules! gen_as_ptr_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let rc_clone: Rc<[$elem], Global> = Rc::clone(&rc); + let _ptr = Rc::<[$elem], Global>::as_ptr(&rc); + let _clone_ptr = Rc::<[$elem], Global>::as_ptr(&rc_clone); + } + }; + } + + gen_as_ptr_harness!(harness_rc_as_ptr_i8, i8); + gen_as_ptr_harness!(harness_rc_as_ptr_i16, i16); + gen_as_ptr_harness!(harness_rc_as_ptr_i32, i32); + gen_as_ptr_harness!(harness_rc_as_ptr_i64, i64); + gen_as_ptr_harness!(harness_rc_as_ptr_i128, i128); + gen_as_ptr_harness!(harness_rc_as_ptr_u8, u8); + gen_as_ptr_harness!(harness_rc_as_ptr_u16, u16); + gen_as_ptr_harness!(harness_rc_as_ptr_u32, u32); + gen_as_ptr_harness!(harness_rc_as_ptr_u64, u64); + gen_as_ptr_harness!(harness_rc_as_ptr_u128, u128); + gen_as_ptr_harness!(harness_rc_as_ptr_unit, ()); + gen_as_ptr_harness!(harness_rc_as_ptr_array, [u8; 4]); + gen_as_ptr_harness!(harness_rc_as_ptr_bool, bool); + gen_as_ptr_harness!(harness_rc_as_ptr_dyn_any, dyn Any); + + gen_as_ptr_unsized_harness!(harness_rc_as_ptr_vec_u8, u8); + gen_as_ptr_unsized_harness!(harness_rc_as_ptr_vec_u16, u16); + gen_as_ptr_unsized_harness!(harness_rc_as_ptr_vec_u32, u32); + gen_as_ptr_unsized_harness!(harness_rc_as_ptr_vec_u64, u64); + gen_as_ptr_unsized_harness!(harness_rc_as_ptr_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2467 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_from_slice_copy_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$ty>(); + let _ = as RcFromSlice<$ty>>::from_slice(vec.as_slice()); + } + }; + } + + gen_from_slice_copy_harness!(harness_from_slice_copy_i8, i8); + gen_from_slice_copy_harness!(harness_from_slice_copy_i16, i16); + gen_from_slice_copy_harness!(harness_from_slice_copy_i32, i32); + gen_from_slice_copy_harness!(harness_from_slice_copy_i64, i64); + gen_from_slice_copy_harness!(harness_from_slice_copy_i128, i128); + gen_from_slice_copy_harness!(harness_from_slice_copy_u8, u8); + gen_from_slice_copy_harness!(harness_from_slice_copy_u16, u16); + gen_from_slice_copy_harness!(harness_from_slice_copy_u32, u32); + gen_from_slice_copy_harness!(harness_from_slice_copy_u64, u64); + gen_from_slice_copy_harness!(harness_from_slice_copy_u128, u128); + gen_from_slice_copy_harness!(harness_from_slice_copy_unit, ()); + gen_from_slice_copy_harness!(harness_from_slice_copy_array, [u8; 4]); + gen_from_slice_copy_harness!(harness_from_slice_copy_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2530 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + // `Rc::drop` has two direct control-flow branches: + // 1) after `dec_strong`, `strong() != 0`: return without calling `drop_slow`; + // 2) after `dec_strong`, `strong() == 0`: call `drop_slow`. + // We cover it with three ownership scenarios: + // - unique strong (`strong == 1`, no weak): dropping enters branch (2) with no weaks; + // - shared strong (`strong > 1`): dropping enters branch (1); + // - unique strong + weak present (`strong == 1`, `weak > 0`): dropping enters branch (2) + // while weaks still exist, which exercises a distinct drop_slow path. + macro_rules! gen_drop_rc_sized { + ($unique:ident, $shared:ident, $weak_present:ident, dyn Any) => { + #[kani::proof] + pub fn $unique() { + // Build a trait-object Rc by upcasting Rc to Rc. + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let rc: Rc = rc_i32; + // Unique drop scenario: strong == 1, weak == 0. + let _ = rc; + } + + #[kani::proof] + pub fn $shared() { + // Build a trait-object Rc by upcasting Rc to Rc. + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let rc: Rc = rc_i32; + // Keep another strong owner alive so dropping `rc` sees strong > 1. + let rc_clone: Rc = Rc::clone(&rc); + { + let _dropped = rc; + } + // Final drop happens when this last strong ref leaves scope. + let _ = rc_clone; + } + + #[kani::proof] + pub fn $weak_present() { + // Build a trait-object Rc by upcasting Rc to Rc. + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let rc: Rc = rc_i32; + // Keep a weak owner so dropping `rc` sees strong == 0 with weak > 0. + let weak: Weak = Rc::downgrade(&rc); + { + let _dropped = rc; + } + // Keep weak alive through the drop point. + let _ = weak; + } + }; + ($unique:ident, $shared:ident, $weak_present:ident, $ty:ty) => { + #[kani::proof] + pub fn $unique() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + // Unique drop scenario: strong == 1, weak == 0. + let _ = rc; + } + + #[kani::proof] + pub fn $shared() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + // Keep another strong owner alive so dropping `rc` sees strong > 1. + let rc_clone: Rc<$ty, Global> = Rc::clone(&rc); + { + let _dropped = rc; + } + // Final drop happens when this last strong ref leaves scope. + let _ = rc_clone; + } + + #[kani::proof] + pub fn $weak_present() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + // Keep a weak owner so dropping `rc` sees strong == 0 with weak > 0. + let weak: Weak<$ty, Global> = Rc::downgrade(&rc); + { + let _dropped = rc; + } + // Keep weak alive through the drop point. + let _ = weak; + } + }; + } + + macro_rules! gen_drop_rc_unsized { + ($unique:ident, $shared:ident, $weak_present:ident, $elem:ty) => { + #[kani::proof] + pub fn $unique() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + // Unique drop scenario: strong == 1, weak == 0. + let _ = rc; + } + + #[kani::proof] + pub fn $shared() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + // Keep another strong owner alive so dropping `rc` sees strong > 1. + let rc_clone: Rc<[$elem], Global> = Rc::clone(&rc); + { + let _dropped = rc; + } + // Final drop happens when this last strong ref leaves scope. + let _ = rc_clone; + } + + #[kani::proof] + pub fn $weak_present() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + // Keep a weak owner so dropping `rc` sees strong == 0 with weak > 0. + let weak: Weak<[$elem], Global> = Rc::downgrade(&rc); + { + let _dropped = rc; + } + // Keep weak alive through the drop point. + let _ = weak; + } + }; + } + + gen_drop_rc_sized!( + harness_drop_rc_i8_unique, + harness_drop_rc_i8_shared, + harness_drop_rc_i8_weak_present, + i8 + ); + gen_drop_rc_sized!( + harness_drop_rc_i16_unique, + harness_drop_rc_i16_shared, + harness_drop_rc_i16_weak_present, + i16 + ); + gen_drop_rc_sized!( + harness_drop_rc_i32_unique, + harness_drop_rc_i32_shared, + harness_drop_rc_i32_weak_present, + i32 + ); + gen_drop_rc_sized!( + harness_drop_rc_i64_unique, + harness_drop_rc_i64_shared, + harness_drop_rc_i64_weak_present, + i64 + ); + gen_drop_rc_sized!( + harness_drop_rc_i128_unique, + harness_drop_rc_i128_shared, + harness_drop_rc_i128_weak_present, + i128 + ); + gen_drop_rc_sized!( + harness_drop_rc_u8_unique, + harness_drop_rc_u8_shared, + harness_drop_rc_u8_weak_present, + u8 + ); + gen_drop_rc_sized!( + harness_drop_rc_u16_unique, + harness_drop_rc_u16_shared, + harness_drop_rc_u16_weak_present, + u16 + ); + gen_drop_rc_sized!( + harness_drop_rc_u32_unique, + harness_drop_rc_u32_shared, + harness_drop_rc_u32_weak_present, + u32 + ); + gen_drop_rc_sized!( + harness_drop_rc_u64_unique, + harness_drop_rc_u64_shared, + harness_drop_rc_u64_weak_present, + u64 + ); + gen_drop_rc_sized!( + harness_drop_rc_u128_unique, + harness_drop_rc_u128_shared, + harness_drop_rc_u128_weak_present, + u128 + ); + gen_drop_rc_sized!( + harness_drop_rc_unit_unique, + harness_drop_rc_unit_shared, + harness_drop_rc_unit_weak_present, + () + ); + gen_drop_rc_sized!( + harness_drop_rc_array_unique, + harness_drop_rc_array_shared, + harness_drop_rc_array_weak_present, + [u8; 4] + ); + gen_drop_rc_sized!( + harness_drop_rc_dyn_any_unique, + harness_drop_rc_dyn_any_shared, + harness_drop_rc_dyn_any_weak_present, + dyn Any + ); + gen_drop_rc_sized!( + harness_drop_rc_bool_unique, + harness_drop_rc_bool_shared, + harness_drop_rc_bool_weak_present, + bool + ); + + gen_drop_rc_unsized!( + harness_drop_rc_vec_u8_unique, + harness_drop_rc_vec_u8_shared, + harness_drop_rc_vec_u8_weak_present, + u8 + ); + gen_drop_rc_unsized!( + harness_drop_rc_vec_u16_unique, + harness_drop_rc_vec_u16_shared, + harness_drop_rc_vec_u16_weak_present, + u16 + ); + gen_drop_rc_unsized!( + harness_drop_rc_vec_u32_unique, + harness_drop_rc_vec_u32_shared, + harness_drop_rc_vec_u32_weak_present, + u32 + ); + gen_drop_rc_unsized!( + harness_drop_rc_vec_u64_unique, + harness_drop_rc_vec_u64_shared, + harness_drop_rc_vec_u64_weak_present, + u64 + ); + gen_drop_rc_unsized!( + harness_drop_rc_vec_u128_unique, + harness_drop_rc_vec_u128_shared, + harness_drop_rc_vec_u128_weak_present, + u128 + ); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2557 { + use core::any::Any; + + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_clone_rc_harness { + ($name:ident, dyn Any) => { + #[kani::proof] + pub fn $name() { + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let rc: Rc = rc_i32; + let _ = Rc::clone(&rc); + } + }; + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let _ = Rc::clone(&rc); + } + }; + } + + macro_rules! gen_clone_rc_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let _ = Rc::clone(&rc); + } + }; + } + + gen_clone_rc_harness!(harness_clone_rc_i8, i8); + gen_clone_rc_harness!(harness_clone_rc_i16, i16); + gen_clone_rc_harness!(harness_clone_rc_i32, i32); + gen_clone_rc_harness!(harness_clone_rc_i64, i64); + gen_clone_rc_harness!(harness_clone_rc_i128, i128); + gen_clone_rc_harness!(harness_clone_rc_u8, u8); + gen_clone_rc_harness!(harness_clone_rc_u16, u16); + gen_clone_rc_harness!(harness_clone_rc_u32, u32); + gen_clone_rc_harness!(harness_clone_rc_u64, u64); + gen_clone_rc_harness!(harness_clone_rc_u128, u128); + gen_clone_rc_harness!(harness_clone_rc_unit, ()); + gen_clone_rc_harness!(harness_clone_rc_array, [u8; 4]); + gen_clone_rc_harness!(harness_clone_rc_bool, bool); + gen_clone_rc_harness!(harness_clone_rc_dyn_any, dyn Any); + + gen_clone_rc_unsized_harness!(harness_clone_rc_vec_u8, u8); + gen_clone_rc_unsized_harness!(harness_clone_rc_vec_u16, u16); + gen_clone_rc_unsized_harness!(harness_clone_rc_vec_u32, u32); + gen_clone_rc_unsized_harness!(harness_clone_rc_vec_u64, u64); + gen_clone_rc_unsized_harness!(harness_clone_rc_vec_u128, u128); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2582 { + use super::*; + + macro_rules! gen_rc_default_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let _ = Rc::<$ty>::default(); + } + }; + } + + gen_rc_default_harness!(harness_rc_default_i8, i8); + gen_rc_default_harness!(harness_rc_default_i16, i16); + gen_rc_default_harness!(harness_rc_default_i32, i32); + gen_rc_default_harness!(harness_rc_default_i64, i64); + gen_rc_default_harness!(harness_rc_default_i128, i128); + gen_rc_default_harness!(harness_rc_default_u8, u8); + gen_rc_default_harness!(harness_rc_default_u16, u16); + gen_rc_default_harness!(harness_rc_default_u32, u32); + gen_rc_default_harness!(harness_rc_default_u64, u64); + gen_rc_default_harness!(harness_rc_default_u128, u128); + gen_rc_default_harness!(harness_rc_default_unit, ()); + gen_rc_default_harness!(harness_rc_default_array, [u8; 4]); + gen_rc_default_harness!(harness_rc_default_bool, bool); + gen_rc_default_harness!(harness_rc_default_vec_u8, Vec); + gen_rc_default_harness!(harness_rc_default_vec_u16, Vec); + gen_rc_default_harness!(harness_rc_default_vec_u32, Vec); + gen_rc_default_harness!(harness_rc_default_vec_u64, Vec); + gen_rc_default_harness!(harness_rc_default_vec_u128, Vec); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2606 { + use super::*; + + #[kani::proof] + pub fn harness_rc_default_str() { + let _ = Rc::::default(); + } +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_2973 { + use super::*; + + macro_rules! gen_from_ref_str_harness { + ($name:ident, $value:expr) => { + #[kani::proof] + pub fn $name() { + let _ = Rc::::from($value); + } + }; + } + + gen_from_ref_str_harness!(harness_from_ref_str_rc_str_empty, ""); + gen_from_ref_str_harness!(harness_from_ref_str_rc_str_nonempty, "test"); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3051 { + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_from_vec_harness { + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let v: Vec<$ty, Global> = verifier_nondet_vec_rc::<$ty>(); + let _ = Rc::<[$ty], Global>::from(v); + } + }; + } + + gen_from_vec_harness!(harness_from_vec_i8, i8); + gen_from_vec_harness!(harness_from_vec_i16, i16); + gen_from_vec_harness!(harness_from_vec_i32, i32); + gen_from_vec_harness!(harness_from_vec_i64, i64); + gen_from_vec_harness!(harness_from_vec_i128, i128); + gen_from_vec_harness!(harness_from_vec_u8, u8); + gen_from_vec_harness!(harness_from_vec_u16, u16); + gen_from_vec_harness!(harness_from_vec_u32, u32); + gen_from_vec_harness!(harness_from_vec_u64, u64); + gen_from_vec_harness!(harness_from_vec_u128, u128); + gen_from_vec_harness!(harness_from_vec_unit, ()); + gen_from_vec_harness!(harness_from_vec_array, [u8; 4]); + gen_from_vec_harness!(harness_from_vec_bool, bool); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_3107 { + use super::*; + + macro_rules! gen_from_rc_str_to_rc_u8_slice_harness { + ($name:ident, $value:expr) => { + #[kani::proof] + pub fn $name() { + let rc: Rc = Rc::from($value); + let _ = >::from(rc); + } + }; + } + + gen_from_rc_str_to_rc_u8_slice_harness!(harness_from_rc_str_to_rc_u8_slice_empty, ""); + gen_from_rc_str_to_rc_u8_slice_harness!(harness_from_rc_str_to_rc_u8_slice_nonempty, "test"); +} + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +mod verify_1528 { + use core::any::Any; + use super::kani_rc_harness_helpers::*; + use super::*; + + macro_rules! gen_into_raw_with_allocator_sized_harness { + ($name:ident, dyn Any) => { + #[kani::proof] + pub fn $name() { + let rc_i32: Rc = Rc::new_in(kani::any::(), Global); + let rc: Rc = rc_i32; + let (ptr, alloc): (*const dyn Any, Global) = + Rc::::into_raw_with_allocator(rc); + let _recovered: Rc = + unsafe { Rc::::from_raw_in(ptr, alloc) }; + } + }; + ($name:ident, $ty:ty) => { + #[kani::proof] + pub fn $name() { + let rc: Rc<$ty, Global> = Rc::new_in(kani::any::<$ty>(), Global); + let (ptr, alloc): (*const $ty, Global) = + Rc::<$ty, Global>::into_raw_with_allocator(rc); + let _recovered: Rc<$ty, Global> = + unsafe { Rc::<$ty, Global>::from_raw_in(ptr, alloc) }; + } + }; + } + + macro_rules! gen_into_raw_with_allocator_unsized_harness { + ($name:ident, $elem:ty) => { + #[kani::proof] + pub fn $name() { + let vec = verifier_nondet_vec_rc::<$elem>(); + let rc: Rc<[$elem], Global> = Rc::from(vec); + let (ptr, alloc): (*const [$elem], Global) = + Rc::<[$elem], Global>::into_raw_with_allocator(rc); + let _recovered: Rc<[$elem], Global> = + unsafe { Rc::<[$elem], Global>::from_raw_in(ptr, alloc) }; + } + }; + } + + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_i8, i8); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_i16, i16); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_i32, i32); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_i64, i64); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_i128, i128); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_u8, u8); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_u16, u16); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_u32, u32); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_u64, u64); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_u128, u128); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_unit, ()); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_bool, bool); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_array, [u8; 4]); + gen_into_raw_with_allocator_sized_harness!(harness_into_raw_with_allocator_dyn_any, dyn Any); + + gen_into_raw_with_allocator_unsized_harness!(harness_into_raw_with_allocator_vec_u8, u8); + gen_into_raw_with_allocator_unsized_harness!(harness_into_raw_with_allocator_vec_u16, u16); + gen_into_raw_with_allocator_unsized_harness!(harness_into_raw_with_allocator_vec_u32, u32); + gen_into_raw_with_allocator_unsized_harness!(harness_into_raw_with_allocator_vec_u64, u64); + gen_into_raw_with_allocator_unsized_harness!(harness_into_raw_with_allocator_vec_u128, u128); +}