1use core::{
4 any,
5 borrow,
6 cmp,
7 convert,
8 fmt,
9 future,
10 hash,
11 iter,
12 marker,
13 mem::{self, MaybeUninit},
14 ops,
15 pin,
16 ptr::{self, NonNull},
17 task,
18};
19
20use alloc::boxed::Box;
21
22#[cfg(feature = "nightly-async-iterator")]
23use core::async_iter;
24
25#[cfg(feature = "nightly-coerce-unsized")]
26use core::ops::CoerceUnsized;
27
28#[cfg(feature = "nightly-dispatch-from-dyn")]
29use core::ops::DispatchFromDyn;
30
31pub struct StaticRc<T: ?Sized, const NUM: usize, const DEN: usize> {
42 pointer: NonNull<T>,
43}
44
45impl<T, const N: usize> StaticRc<T, N, N> {
46 #[inline(always)]
61 pub fn new(value: T) -> Self
62 where
63 AssertLeType!(1, N): Sized,
64 {
65 #[cfg(not(feature = "compile-time-ratio"))]
66 assert!(N > 0);
67
68 let pointer = NonNull::from(Box::leak(Box::new(value)));
69 Self { pointer }
70 }
71
72 #[inline(always)]
85 pub fn pin(value: T) -> pin::Pin<Self>
86 where
87 AssertLeType!(1, N): Sized,
88 {
89 #[cfg(not(feature = "compile-time-ratio"))]
90 assert!(N > 0);
91
92 unsafe { pin::Pin::new_unchecked(Self::new(value)) }
95 }
96
97 #[inline(always)]
110 pub fn into_inner(this: Self) -> T {
111 let boxed = unsafe { Box::from_raw(this.pointer.as_ptr()) };
114 mem::forget(this);
115
116 *boxed
117 }
118}
119
120impl<T: ?Sized, const N: usize> StaticRc<T, N, N> {
121 #[inline(always)]
136 pub fn get_mut(this: &mut Self) -> &mut T {
137 unsafe { this.pointer.as_mut() }
140 }
141
142 #[inline(always)]
156 pub fn into_box(this: Self) -> Box<T> {
157 let pointer = this.pointer;
158 mem::forget(this);
159
160 unsafe { Box::from_raw(pointer.as_ptr()) }
164 }
165}
166
167impl<T: ?Sized, const NUM: usize, const DEN: usize> StaticRc<T, NUM, DEN> {
168 #[inline(always)]
186 pub fn into_raw(this: Self) -> NonNull<T> {
187 let pointer = this.pointer;
188 mem::forget(this);
189
190 pointer
191 }
192
193 #[inline(always)]
210 pub fn as_ptr(this: &Self) -> NonNull<T> { this.pointer }
211
212 #[inline(always)]
225 pub fn get_ref(this: &Self) -> &T {
226 unsafe { this.pointer.as_ref() }
229 }
230
231 #[inline(always)]
259 pub unsafe fn from_raw(pointer: NonNull<T>) -> Self
260 where
261 AssertLeType!(1, NUM): Sized,
262 {
263 #[cfg(not(feature = "compile-time-ratio"))]
264 assert!(NUM > 0);
265
266 Self { pointer }
267 }
268
269 #[inline(always)]
286 pub fn ptr_eq<const N: usize, const D: usize>(this: &Self, other: &StaticRc<T, N, D>) -> bool {
287 StaticRc::as_ptr(this) == StaticRc::as_ptr(other)
288 }
289
290 #[inline(always)]
309 pub fn adjust<const N: usize, const D: usize>(this: Self) -> StaticRc<T, N, D>
310 where
311 AssertLeType!(1, N): Sized,
312 AssertEqType!(N * DEN, NUM * D): Sized,
313 {
314 #[cfg(not(feature = "compile-time-ratio"))]
315 {
316 assert!(N > 0);
317 assert_eq!(NUM * D, N * DEN, "{} / {} != {} / {}", NUM, DEN, N, D);
318 }
319
320 let pointer = this.pointer;
321 mem::forget(this);
322
323 StaticRc { pointer }
324 }
325
326 #[inline(always)]
350 pub fn as_rcref<'a>(this: &'a mut Self) -> super::StaticRcRef<'a, T, NUM, DEN>
351 where
352 AssertLeType!(1, NUM): Sized,
353 {
354 let ptr = this.pointer;
371 unsafe {
372 super::StaticRcRef::from_raw(ptr)
373 }
374 }
375
376 #[inline(always)]
398 pub fn split<const A: usize, const B: usize>(this: Self) -> (StaticRc<T, A, DEN>, StaticRc<T, B, DEN>)
399 where
400 AssertLeType!(1, A): Sized,
401 AssertLeType!(1, B): Sized,
402 AssertEqType!(A + B, NUM): Sized,
403 {
404 #[cfg(not(feature = "compile-time-ratio"))]
405 {
406 assert!(A > 0);
407 assert!(B > 0);
408 assert_eq!(NUM, A + B, "{} != {} + {}", NUM, A, B);
409 }
410
411 let pointer = this.pointer;
412 mem::forget(this);
413
414 (StaticRc { pointer }, StaticRc { pointer })
415 }
416
417 #[inline(always)]
438 pub fn split_array<const N: usize, const DIM: usize>(this: Self) -> [StaticRc<T, N, DEN>; DIM]
439 where
440 AssertEqType!(N * DIM, NUM ): Sized,
441 AssertLeType!(mem::size_of::<[StaticRc<T, N, DEN>; DIM]>(), usize::MAX / 2 + 1): Sized,
442 {
443 #[cfg(not(feature = "compile-time-ratio"))]
444 assert_eq!(NUM, N * DIM, "{} != {} * {}", NUM, N, DIM);
445
446 #[cfg(not(feature = "compile-time-ratio"))]
447 assert!(mem::size_of::<[StaticRc<T, N, DEN>; DIM]>() <= (isize::MAX as usize),
448 "Size of result ({}) exceeeds isize::MAX", mem::size_of::<[StaticRc<T, N, DEN>; DIM]>());
449
450 let pointer = this.pointer;
451 mem::forget(this);
452
453 let mut array = MaybeUninit::uninit();
454
455 for i in 0..DIM {
456 let destination = unsafe { (array.as_mut_ptr() as *mut StaticRc<T, N, DEN>).add(i) };
461
462 unsafe { ptr::write(destination, StaticRc { pointer }); }
466 }
467
468 unsafe { array.assume_init() }
471 }
472
473 #[inline(always)]
495 pub fn join<const A: usize, const B: usize>(left: StaticRc<T, A, DEN>, right: StaticRc<T, B, DEN>) -> Self
496 where
497 AssertEqType!(NUM, A + B): Sized,
498 {
499 let (left, right) = Self::validate_pair(left, right);
500
501 unsafe { Self::join_impl(left, right) }
504 }
505
506 #[inline(always)]
534 pub unsafe fn join_unchecked<const A: usize, const B: usize>(
535 left: StaticRc<T, A, DEN>,
536 right: StaticRc<T, B, DEN>,
537 ) -> Self
538 where
539 AssertEqType!(NUM, A + B): Sized,
540 {
541 #[cfg(debug_assertions)]
542 let (left, right) = Self::validate_pair(left, right);
543
544 Self::join_impl(left, right)
545 }
546
547 #[inline(always)]
569 pub fn join_array<const N: usize, const DIM: usize>(array: [StaticRc<T, N, DEN>; DIM]) -> Self
570 where
571 AssertLeType!(1, NUM): Sized,
572 AssertEqType!(N * DIM, NUM): Sized,
573 {
574 let array = Self::validate_array(array);
575
576 unsafe { Self::join_array_impl(array) }
577 }
578
579 #[inline(always)]
601 pub unsafe fn join_array_unchecked<const N: usize, const DIM: usize>(array: [StaticRc<T, N, DEN>; DIM])
602 -> Self
603 where
604 AssertLeType!(1, NUM): Sized,
605 AssertEqType!(N * DIM, NUM): Sized,
606 {
607 #[cfg(debug_assertions)]
608 let array = Self::validate_array(array);
609
610 Self::join_array_impl(array)
611 }
612
613 #[inline(always)]
615 unsafe fn join_impl<const A: usize, const B: usize>(
616 left: StaticRc<T, A, DEN>,
617 right: StaticRc<T, B, DEN>,
618 ) -> Self
619 where
620 AssertEqType!(NUM, A + B): Sized,
621 {
622 #[cfg(not(feature = "compile-time-ratio"))]
623 if NUM != A + B {
624 mem::forget(left);
625 mem::forget(right);
626
627 panic!("{} != {} + {}", NUM, A, B);
628 }
629
630 let pointer = left.pointer;
631 mem::forget(left);
632 mem::forget(right);
633
634 Self { pointer }
635 }
636
637 #[inline(always)]
639 unsafe fn join_array_impl<const N: usize, const DIM: usize>(array: [StaticRc<T, N, DEN>; DIM])
640 -> Self
641 where
642 AssertLeType!(1, NUM): Sized,
643 AssertEqType!(N * DIM, NUM): Sized,
644 {
645 #[cfg(not(feature = "compile-time-ratio"))]
646 {
647 if NUM <= 0 {
648 mem::forget(array);
649
650 panic!("NUM <= 0");
651 }
652 if NUM != N * DIM {
653 mem::forget(array);
654
655 panic!("{} != {} * {}", NUM, N, DIM);
656 }
657 }
658
659 let pointer = array[0].pointer;
660 mem::forget(array);
661
662 Self { pointer, }
663 }
664
665 fn validate_pair<const A: usize, const B: usize>(left: StaticRc<T, A, DEN>, right: StaticRc<T, B, DEN>)
666 -> (StaticRc<T, A, DEN>, StaticRc<T, B, DEN>)
667 {
668 if StaticRc::ptr_eq(&left, &right) {
669 return (left, right);
670 }
671
672 let left = StaticRc::into_raw(left);
673 let right = StaticRc::into_raw(right);
674
675 panic!("Cannot join pair with multiple origins: {:?} != {:?}", left.as_ptr(), right.as_ptr());
676 }
677
678 fn validate_array<const N: usize, const DIM: usize>(array: [StaticRc<T, N, DEN>; DIM]) -> [StaticRc<T, N, DEN>; DIM] {
679 let first = &array[0];
680 let divergent = array[1..].iter().find(|e| !StaticRc::ptr_eq(&first, e));
681
682 if let Some(divergent) = divergent {
683 let first = first.pointer.as_ptr();
684 let divergent = divergent.pointer.as_ptr();
685
686 mem::forget(array);
687
688 panic!("Cannot join array with multiple origins: {:?} != {:?}", first, divergent);
689 }
690
691 array
692 }
693}
694
695impl<const NUM: usize, const DEN: usize> StaticRc<dyn any::Any, NUM, DEN> {
696 pub fn downcast<T: any::Any>(self) -> Result<StaticRc<T, NUM, DEN>, Self> {
698 if Self::get_ref(&self).is::<T>() {
699 let pointer = Self::into_raw(self).cast::<T>();
700 Ok(StaticRc { pointer })
701 } else {
702 Err(self)
703 }
704 }
705}
706
707impl<T: ?Sized, const NUM: usize, const DEN: usize> Drop for StaticRc<T, NUM, DEN> {
708 #[inline(always)]
709 fn drop(&mut self) {
710 debug_assert_eq!(NUM, DEN, "{} != {}", NUM, DEN);
711
712 if NUM == DEN {
713 unsafe { Box::from_raw(self.pointer.as_ptr()) };
717 }
718 }
719}
720
721impl<T: ?Sized, const N: usize> convert::AsMut<T> for StaticRc<T, N, N> {
722 #[inline(always)]
723 fn as_mut(&mut self) -> &mut T { Self::get_mut(self) }
724}
725
726impl<T: ?Sized, const NUM: usize, const DEN: usize> convert::AsRef<T> for StaticRc<T, NUM, DEN> {
727 #[inline(always)]
728 fn as_ref(&self) -> &T { Self::get_ref(self) }
729}
730
731impl<T: ?Sized, const NUM: usize, const DEN: usize> borrow::Borrow<T> for StaticRc<T, NUM, DEN> {
732 #[inline(always)]
733 fn borrow(&self) -> &T { Self::get_ref(self) }
734}
735
736impl<T: ?Sized, const N: usize> borrow::BorrowMut<T> for StaticRc<T, N, N> {
737 #[inline(always)]
738 fn borrow_mut(&mut self) -> &mut T { Self::get_mut(self) }
739}
740
741#[cfg(feature = "nightly-coerce-unsized")]
742impl<T, U, const NUM: usize, const DEN: usize> CoerceUnsized<StaticRc<U, NUM, DEN>> for StaticRc<T, NUM, DEN>
743where
744 T: ?Sized + marker::Unsize<U>,
745 U: ?Sized,
746{}
747
748impl<T: ?Sized + fmt::Debug, const NUM: usize, const DEN: usize> fmt::Debug for StaticRc<T, NUM, DEN> {
749 #[inline(always)]
750 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
751 fmt::Debug::fmt(Self::get_ref(self), f)
752 }
753}
754
755impl<T: Default, const N: usize> Default for StaticRc<T, N, N>
756where
757 AssertLeType!(1, N): Sized,
758{
759 #[inline(always)]
760 fn default() -> Self { Self::new(T::default()) }
761}
762
763impl<T: ?Sized, const NUM: usize, const DEN: usize> ops::Deref for StaticRc<T, NUM, DEN> {
764 type Target = T;
765
766 #[inline(always)]
767 fn deref(&self) -> &T { Self::get_ref(self) }
768}
769
770impl<T: ?Sized, const N: usize> ops::DerefMut for StaticRc<T, N, N> {
771 #[inline(always)]
772 fn deref_mut(&mut self) -> &mut T { Self::get_mut(self) }
773}
774
775impl<T: ?Sized + fmt::Display, const NUM: usize, const DEN: usize> fmt::Display for StaticRc<T, NUM, DEN> {
776 #[inline(always)]
777 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
778 fmt::Display::fmt(Self::get_ref(self), f)
779 }
780}
781
782#[cfg(feature = "nightly-dispatch-from-dyn")]
783impl<T, U, const NUM: usize, const DEN: usize> DispatchFromDyn<StaticRc<U, NUM, DEN>> for StaticRc<T, NUM, DEN>
784where
785 T: ?Sized + marker::Unsize<U>,
786 U: ?Sized,
787{}
788
789impl<I: iter::DoubleEndedIterator + ?Sized, const N: usize> iter::DoubleEndedIterator for StaticRc<I, N, N> {
790 #[inline(always)]
791 fn next_back(&mut self) -> Option<I::Item> { Self::get_mut(self).next_back() }
792
793 #[inline(always)]
794 fn nth_back(&mut self, n: usize) -> Option<I::Item> { Self::get_mut(self).nth_back(n) }
795}
796
797impl<T: ?Sized + cmp::Eq, const NUM: usize, const DEN: usize> cmp::Eq for StaticRc<T, NUM, DEN> {}
798
799impl<I: iter::ExactSizeIterator + ?Sized, const N: usize> iter::ExactSizeIterator for StaticRc<I, N, N> {
800 #[inline(always)]
801 fn len(&self) -> usize { Self::get_ref(self).len() }
802}
803
804impl<T: ?Sized, const N: usize> From<Box<T>> for StaticRc<T, N, N> {
805 #[inline(always)]
806 fn from(value: Box<T>) -> Self {
807 let pointer = NonNull::from(Box::leak(value));
808 Self { pointer }
809 }
810}
811
812impl<T: Copy, const N: usize> From<&'_ [T]> for StaticRc<[T], N, N> {
813 #[inline(always)]
814 fn from(value: &[T]) -> Self { Self::from(Box::from(value)) }
815}
816
817impl<const N: usize> From<&'_ str> for StaticRc<str, N, N> {
818 #[inline(always)]
819 fn from(value: &str) -> Self { Self::from(Box::from(value)) }
820}
821
822impl<T, const LEN: usize, const N: usize> From<[T; LEN]> for StaticRc<[T], N, N> {
823 #[inline(always)]
824 fn from(value: [T; LEN]) -> Self { Self::from(Box::from(value)) }
825}
826
827impl<T: Copy, const N: usize> From<alloc::borrow::Cow<'_, [T]>> for StaticRc<[T], N, N> {
828 #[inline(always)]
829 fn from(value: alloc::borrow::Cow<'_, [T]>) -> Self { Self::from(Box::from(value)) }
830}
831
832impl<const N: usize> From<alloc::borrow::Cow<'_, str>> for StaticRc<str, N, N> {
833 #[inline(always)]
834 fn from(value: alloc::borrow::Cow<'_, str>) -> Self { Self::from(Box::from(value)) }
835}
836
837impl<const N: usize> From<alloc::string::String> for StaticRc<str, N, N> {
838 #[inline(always)]
839 fn from(value: alloc::string::String) -> Self { Self::from(Box::from(value)) }
840}
841
842impl<T, const N: usize> From<T> for StaticRc<T, N, N> {
843 #[inline(always)]
844 fn from(value: T) -> Self { Self::from(Box::from(value)) }
845}
846
847impl<T, const N: usize> From<alloc::vec::Vec<T>> for StaticRc<[T], N, N> {
848 #[inline(always)]
849 fn from(value: alloc::vec::Vec<T>) -> Self { Self::from(Box::from(value)) }
850}
851
852impl<T, const N: usize> From<StaticRc<[T], N, N>> for alloc::vec::Vec<T> {
853 #[inline(always)]
854 fn from(value: StaticRc<[T], N, N>) -> Self { Self::from(StaticRc::into_box(value)) }
855}
856
857impl<T: ?Sized, const N: usize> From<StaticRc<T, N, N>> for alloc::rc::Rc<T> {
858 #[inline(always)]
859 fn from(value: StaticRc<T, N, N>) -> Self { Self::from(StaticRc::into_box(value)) }
860}
861
862impl<T: ?Sized, const N: usize> From<StaticRc<T, N, N>> for alloc::sync::Arc<T> {
863 #[inline(always)]
864 fn from(value: StaticRc<T, N, N>) -> Self { Self::from(StaticRc::into_box(value)) }
865}
866
867impl<const N: usize> From<StaticRc<str, N, N>> for alloc::string::String {
868 #[inline(always)]
869 fn from(value: StaticRc<str, N, N>) -> Self { Self::from(StaticRc::into_box(value)) }
870}
871
872impl<const NUM: usize, const DEN: usize> From<StaticRc<str, NUM, DEN>> for StaticRc<[u8], NUM, DEN> {
873 #[inline(always)]
874 fn from(value: StaticRc<str, NUM, DEN>) -> Self {
875 let pointer = value.pointer.as_ptr() as *mut [u8];
876 mem::forget(value);
877
878 debug_assert!(!pointer.is_null());
881 let pointer = unsafe { NonNull::new_unchecked(pointer) };
882
883 Self { pointer }
884 }
885}
886
887impl<const N: usize> iter::FromIterator<StaticRc<str, N, N>> for alloc::string::String {
888 #[inline(always)]
889 fn from_iter<I: IntoIterator<Item = StaticRc<str, N, N>>>(iter: I) -> Self {
890 Self::from_iter(iter.into_iter().map(StaticRc::into_box))
891 }
892}
893
894impl<T, const N: usize> iter::FromIterator<T> for StaticRc<[T], N, N> {
895 #[inline(always)]
896 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { Self::from(Box::from_iter(iter)) }
897}
898
899impl<I: iter::FusedIterator + ?Sized, const N: usize> iter::FusedIterator for StaticRc<I, N, N> {}
900
901impl<F: ?Sized + future::Future + marker::Unpin, const N: usize> future::Future for StaticRc<F, N, N> {
902 type Output = F::Output;
903
904 fn poll(mut self: pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
905 F::poll(pin::Pin::new(&mut *self), cx)
906 }
907}
908
909#[cfg(feature = "nightly-generator-trait")]
910impl<G: ?Sized + ops::Generator<R> + marker::Unpin, R, const N: usize> ops::Generator<R> for StaticRc<G, N, N> {
911 type Yield = G::Yield;
912 type Return = G::Return;
913
914 fn resume(mut self: pin::Pin<&mut Self>, arg: R) -> ops::GeneratorState<Self::Yield, Self::Return> {
915 G::resume(pin::Pin::new(&mut *self), arg)
916 }
917}
918
919#[cfg(feature = "nightly-generator-trait")]
920impl<G: ?Sized + ops::Generator<R>, R, const N: usize> ops::Generator<R> for pin::Pin<StaticRc<G, N, N>> {
921 type Yield = G::Yield;
922 type Return = G::Return;
923
924 fn resume(mut self: pin::Pin<&mut Self>, arg: R) -> ops::GeneratorState<Self::Yield, Self::Return> {
925 G::resume((*self).as_mut(), arg)
926 }
927}
928
929impl<T: ?Sized + hash::Hash, const NUM: usize, const DEN: usize> hash::Hash for StaticRc<T, NUM, DEN> {
930 #[inline(always)]
931 fn hash<H: hash::Hasher>(&self, state: &mut H) {
932 Self::get_ref(self).hash(state);
933 }
934}
935
936impl<I: iter::Iterator + ?Sized, const N: usize> iter::Iterator for StaticRc<I, N, N> {
937 type Item = I::Item;
938
939 #[inline(always)]
940 fn next(&mut self) -> Option<I::Item> { Self::get_mut(self).next() }
941
942 #[inline(always)]
943 fn size_hint(&self) -> (usize, Option<usize>) { Self::get_ref(self).size_hint() }
944
945 #[inline(always)]
946 fn nth(&mut self, n: usize) -> Option<I::Item> { Self::get_mut(self).nth(n) }
947
948 #[inline(always)]
949 fn last(self) -> Option<I::Item> { Self::into_box(self).last() }
950}
951
952impl<T: ?Sized + cmp::Ord, const NUM: usize, const DEN: usize> cmp::Ord for StaticRc<T, NUM, DEN> {
953 #[inline(always)]
954 fn cmp(&self, other: &Self) -> cmp::Ordering {
955 if Self::ptr_eq(self, other) {
956 cmp::Ordering::Equal
957 } else {
958 Self::get_ref(self).cmp(Self::get_ref(other))
959 }
960 }
961}
962
963impl<T, const NUM: usize, const DEN: usize, const N: usize, const D: usize> cmp::PartialEq<StaticRc<T, N, D>>
964 for StaticRc<T, NUM, DEN>
965where
966 T: ?Sized + PartialEq<T>
967{
968 #[inline(always)]
969 fn eq(&self, other: &StaticRc<T, N, D>) -> bool { Self::get_ref(self).eq(StaticRc::get_ref(other)) }
970
971 #[inline(always)]
972 fn ne(&self, other: &StaticRc<T, N, D>) -> bool { Self::get_ref(self).ne(StaticRc::get_ref(other)) }
973}
974
975impl<T, const NUM: usize, const DEN: usize, const N: usize, const D: usize> cmp::PartialOrd<StaticRc<T, N, D>>
976 for StaticRc<T, NUM, DEN>
977where
978 T: ?Sized + PartialOrd<T>
979{
980 #[inline(always)]
981 fn partial_cmp(&self, other: &StaticRc<T, N, D>) -> Option<cmp::Ordering> {
982 Self::get_ref(self).partial_cmp(StaticRc::get_ref(other))
983 }
984
985 #[inline(always)]
986 fn lt(&self, other: &StaticRc<T, N, D>) -> bool {
987 Self::get_ref(self).lt(StaticRc::get_ref(other))
988 }
989
990 #[inline(always)]
991 fn le(&self, other: &StaticRc<T, N, D>) -> bool {
992 Self::get_ref(self).le(StaticRc::get_ref(other))
993 }
994
995 #[inline(always)]
996 fn gt(&self, other: &StaticRc<T, N, D>) -> bool {
997 Self::get_ref(self).gt(StaticRc::get_ref(other))
998 }
999
1000 #[inline(always)]
1001 fn ge(&self, other: &StaticRc<T, N, D>) -> bool {
1002 Self::get_ref(self).ge(StaticRc::get_ref(other))
1003 }
1004}
1005
1006impl<T: ?Sized, const NUM: usize, const DEN: usize> fmt::Pointer for StaticRc<T, NUM, DEN> {
1007 #[inline(always)]
1008 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1009 fmt::Pointer::fmt(&Self::as_ptr(self).as_ptr(), f)
1010 }
1011}
1012
1013#[cfg(feature = "nightly-async-iterator")]
1014impl<S: ?Sized + async_iter::AsyncIterator + marker::Unpin, const N: usize> async_iter::AsyncIterator for StaticRc<S, N, N> {
1015 type Item = S::Item;
1016
1017 fn poll_next(mut self: pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Option<Self::Item>> {
1018 pin::Pin::new(&mut **self).poll_next(cx)
1019 }
1020
1021 fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
1022}
1023
1024impl<T: ?Sized, const NUM: usize, const DEN: usize> marker::Unpin for StaticRc<T, NUM, DEN> {}
1025
1026unsafe impl<T: ?Sized + marker::Send, const NUM: usize, const DEN: usize> marker::Send for StaticRc<T, NUM, DEN> {}
1027
1028unsafe impl<T: ?Sized + marker::Sync, const NUM: usize, const DEN: usize> marker::Sync for StaticRc<T, NUM, DEN> {}
1029
1030#[doc(hidden)]
1031pub mod compile_tests {
1032
1033pub fn rc_reborrow_and_move() {}
1042
1043pub fn rc_reborrow_and_use() {}
1052
1053} #[doc(hidden)]
1056#[cfg(feature = "compile-time-ratio")]
1057pub mod compile_ratio_tests {
1058
1059pub fn rc_new_zero() {}
1065
1066pub fn rc_pin_zero() {}
1072
1073pub fn rc_from_raw_zero() {}
1081
1082pub fn rc_adjust_zero() {}
1090
1091pub fn rc_adjust_ratio() {}
1099
1100pub fn rc_split_zero_first() {}
1108
1109pub fn rc_split_zero_second() {}
1117
1118pub fn rc_split_sum() {}
1126
1127pub fn rc_split_array_ratio() {}
1135
1136pub fn rc_join_ratio() {}
1145
1146pub fn rc_join_unchecked_ratio() {}
1155
1156pub fn rc_join_array_ratio() {}
1165
1166pub fn rc_join_array_unchecked_ratio() {}
1175
1176} #[cfg(all(test, not(feature = "compile-time-ratio")))]
1179mod panic_ratio_tests {
1180
1181use super::*;
1182
1183type Zero = StaticRc<i32, 0, 0>;
1184type One = StaticRc<i32, 1, 1>;
1185type Two = StaticRc<i32, 2, 2>;
1186
1187#[test]
1188#[should_panic]
1189fn rc_new_zero() {
1190 Zero::new(42);
1191}
1192
1193#[test]
1194#[should_panic]
1195fn rc_pin_zero() {
1196 Zero::pin(42);
1197}
1198
1199#[test]
1200#[should_panic]
1201fn rc_from_raw_zero() {
1202 let pointer = NonNull::dangling();
1203
1204 unsafe { Zero::from_raw(pointer) };
1205}
1206
1207#[test]
1208#[should_panic]
1209fn rc_adjust_zero() {
1210 let rc = One::new(42);
1211
1212 One::adjust::<0, 0>(rc);
1213}
1214
1215#[test]
1216#[should_panic]
1217fn rc_adjust_ratio() {
1218 let rc = One::new(42);
1219
1220 One::adjust::<2, 3>(rc);
1221}
1222
1223#[test]
1224#[should_panic]
1225fn rc_split_zero_first() {
1226 let rc = Two::new(42);
1227
1228 Two::split::<0, 2>(rc);
1229}
1230
1231#[test]
1232#[should_panic]
1233fn rc_split_zero_second() {
1234 let rc = Two::new(42);
1235
1236 Two::split::<0, 2>(rc);
1237}
1238
1239#[test]
1240#[should_panic]
1241fn rc_split_sum() {
1242 let rc = Two::new(42);
1243
1244 Two::split::<1, 2>(rc);
1245}
1246
1247#[test]
1248#[should_panic]
1249fn rc_split_array_ratio() {
1250 let rc = Two::new(42);
1251
1252 Two::split_array::<2, 2>(rc);
1253}
1254
1255#[test]
1256#[should_panic]
1257fn rc_join_ratio() {
1258 let rc = Two::new(42);
1259 will_leak(&rc);
1260
1261 let (one, two) = Two::split::<1, 1>(rc);
1262
1263 StaticRc::<_, 1, 2>::join(one, two);
1264}
1265
1266#[test]
1267#[should_panic]
1268fn rc_join_different() {
1269 let (rc, other) = (Two::new(42), Two::new(33));
1270 will_leak(&rc);
1271 will_leak(&other);
1272
1273 let (one, two) = Two::split::<1, 1>(rc);
1274 let (other_one, other_two) = Two::split::<1, 1>(other);
1275
1276 mem::forget([two, other_two]);
1277
1278 Two::join(one, other_one);
1279}
1280
1281#[test]
1282#[should_panic]
1283fn rc_join_unchecked_ratio() {
1284 let rc = Two::new(42);
1285 will_leak(&rc);
1286
1287 let (one, two) = Two::split::<1, 1>(rc);
1288
1289 unsafe { StaticRc::<_, 1, 2>::join_unchecked(one, two) };
1290}
1291
1292#[test]
1293#[should_panic]
1294fn rc_join_array_ratio() {
1295 let rc = Two::new(42);
1296 will_leak(&rc);
1297
1298 let array: [_; 2] = Two::split_array::<1, 2>(rc);
1299
1300 StaticRc::<_, 1, 2>::join_array(array);
1301}
1302
1303#[test]
1304#[should_panic]
1305fn rc_join_array_different() {
1306 let (rc, other) = (Two::new(42), Two::new(33));
1307 will_leak(&rc);
1308 will_leak(&other);
1309
1310 let (one, two) = Two::split::<1, 1>(rc);
1311 let (other_one, other_two) = Two::split::<1, 1>(other);
1312
1313 mem::forget([two, other_two]);
1314
1315 Two::join_array([one, other_one]);
1316}
1317
1318#[test]
1319#[should_panic]
1320fn rc_join_array_unchecked_ratio() {
1321 let rc = Two::new(42);
1322 will_leak(&rc);
1323
1324 let array = Two::split_array::<1, 2>(rc);
1325
1326 unsafe { StaticRc::<_, 1, 2>::join_array_unchecked(array) };
1327}
1328
1329fn will_leak<T, const NUM: usize, const DEN: usize>(_rc: &StaticRc<T, NUM, DEN>) {
1331 #[cfg(miri)]
1332 {
1333 unsafe { miri_static_root(StaticRc::as_ptr(_rc).as_ptr() as *const u8) };
1334 }
1335}
1336
1337#[cfg(miri)]
1338extern "Rust" {
1339 fn miri_static_root(ptr: *const u8);
1345}
1346
1347}