1use crate::prelude::*;
2#[cfg(creusot)]
3use crate::std::ptr::PointerExt as _;
4#[cfg(creusot)]
5use std::ops::Deref;
6use std::rc::Rc;
7#[cfg(feature = "nightly")]
8use std::{alloc::Allocator, boxed::Box};
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 #[trusted(positive(T))]
51 type Rc<T>;
52
53 impl<T> Rc<T> {
54 #[check(terminates)] #[ensures(*result@ == value)]
59 fn new(value: T) -> Self;
60 }
61
62 impl<T, A: Allocator> Rc<T, A> {
63 #[check(ghost)]
64 #[ensures(result == this.as_ptr_logic())]
65 #[ensures(!result.is_null_logic())]
66 fn as_ptr(this: &Rc<T, A>) -> *const T;
67
68 #[check(ghost)]
69 #[ensures(result == (this.as_ptr_logic().addr_logic() == other.as_ptr_logic().addr_logic()))]
70 #[ensures(result ==> this == other)]
71 fn ptr_eq(this: &Rc<T, A>, other: &Rc<T, A>) -> bool;
72 }
73
74
75 impl<T, A: Allocator> AsRef<T> for Rc<T, A> {
76 #[check(ghost)]
77 #[ensures(*result == *(*self)@)]
78 fn as_ref(&self) -> &T;
79 }
80
81 impl<T: ?Sized, A: Allocator + Clone> Clone for Rc<T, A> {
82 #[check(terminates)] #[ensures(result == *self)]
84 fn clone(&self) -> Rc<T, A>;
85 }
86
87 impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {
88 #[check(ghost)]
89 #[ensures(*result == *(*self)@)]
90 fn deref(&self) -> &T { self.as_ref() }
91 }
92}
93
94#[cfg(not(feature = "nightly"))]
96impl<T: DeepModel> DeepModel for Rc<T> {
97 type DeepModelTy = T::DeepModelTy;
98}
99
100#[cfg(not(feature = "nightly"))]
101impl<T> View for Rc<T> {
102 type ViewTy = T;
103}