1use crate::prelude::*;
2#[cfg(creusot)]
3use crate::std::ptr::PointerExt as _;
4use alloc::rc::Rc;
5#[cfg(feature = "nightly")]
6use alloc::{alloc::Allocator, boxed::Box};
7#[cfg(creusot)]
8use core::ops::Deref;
9
10pub trait RcExt {
12 type Pointee: ?Sized;
14
15 #[logic]
19 fn as_ptr_logic(self) -> *const Self::Pointee;
20}
21
22#[cfg(feature = "nightly")]
23impl<T: ?Sized, A: Allocator> RcExt for Rc<T, A> {
24 type Pointee = T;
25 #[logic(opaque)]
26 fn as_ptr_logic(self) -> *const T {
27 dead
28 }
29}
30
31#[cfg(feature = "nightly")]
32impl<T: DeepModel + ?Sized, A: Allocator> DeepModel for Rc<T, A> {
33 type DeepModelTy = T::DeepModelTy;
34 #[logic(open, inline)]
35 fn deep_model(self) -> Self::DeepModelTy {
36 pearlite! { *self.view().deep_model() }
37 }
38}
39
40#[cfg(feature = "nightly")]
41impl<T: ?Sized, A: Allocator> View for Rc<T, A> {
42 type ViewTy = Box<T>;
43 #[logic(opaque)]
44 fn view(self) -> Self::ViewTy {
45 dead
46 }
47}
48
49extern_spec! {
50 mod alloc {
51 mod rc {
52 impl<T> Rc<T> {
53 #[check(ghost)]
54 #[ensures(*result@ == value)]
55 fn new(value: T) -> Self;
56 }
57
58 impl<T, A: Allocator> Rc<T, A> {
59 #[check(ghost)]
60 #[ensures(result == this.as_ptr_logic())]
61 #[ensures(!result.is_null_logic())]
62 fn as_ptr(this: &Rc<T, A>) -> *const T;
63
64 #[check(terminates)] #[ensures(result == (this.as_ptr_logic().deep_model() == other.as_ptr_logic().deep_model()))]
66 #[ensures(result ==> this@ == other@)]
67 fn ptr_eq(this: &Rc<T, A>, other: &Rc<T, A>) -> bool;
68 }
69
70
71 impl<T, A: Allocator> AsRef for Rc<T, A> {
72 #[check(ghost)]
73 #[ensures(*result == *(*self)@)]
74 fn as_ref(&self) -> &T;
75 }
76 }
77 }
78
79 impl<T: ?Sized, A: Allocator + Clone> Clone for Rc<T, A> {
80 #[check(ghost)]
81 #[ensures(result == *self)]
82 fn clone(&self) -> Rc<T, A>;
83 }
84
85 impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {
86 #[check(ghost)]
87 #[ensures(*result == *(*self)@)]
88 fn deref(&self) -> &T { self.as_ref() }
89 }
90}
91
92#[cfg(not(feature = "nightly"))]
94impl<T: DeepModel> DeepModel for Rc<T> {
95 type DeepModelTy = T::DeepModelTy;
96}
97
98#[cfg(not(feature = "nightly"))]
99impl<T> View for Rc<T> {
100 type ViewTy = T;
101}