1#![deny(missing_docs)]
32
33#[cfg(debug_assertions)]
34extern crate backtrace;
35
36#[cfg(debug_assertions)]
37use std::cell::RefCell as StdRefCell;
38use std::cell::{Cell, UnsafeCell};
39use std::ops::{Deref, DerefMut};
40
41pub struct RefCell<T: ?Sized> {
43 borrow: BorrowFlag,
44 value: UnsafeCell<T>,
45}
46
47#[cfg(not(debug_assertions))]
48type Location = ();
49
50#[cfg(debug_assertions)]
51type Location = backtrace::Backtrace;
52
53#[derive(Copy, Clone, PartialEq, Eq, Debug)]
55pub enum BorrowState {
56 Reading,
58 Writing,
60 Unused,
62}
63
64struct BorrowFlag {
67 flag: Cell<usize>,
68
69 #[cfg(debug_assertions)]
70 locations: StdRefCell<Vec<Location>>,
71}
72
73const UNUSED: usize = 0;
74const WRITING: usize = !0;
75
76impl<T> RefCell<T> {
77 pub fn new(value: T) -> RefCell<T> {
79 RefCell {
80 borrow: BorrowFlag::new(),
81 value: UnsafeCell::new(value),
82 }
83 }
84
85 pub fn into_inner(self) -> T {
87 debug_assert!(self.borrow.flag.get() == UNUSED);
88 unsafe { self.value.into_inner() }
89 }
90}
91
92impl<T: ?Sized> RefCell<T> {
93 #[cfg_attr(debug_assertions, inline(never))]
102 pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
103 match BorrowRef::new(&self.borrow) {
104 Some(b) => Ref {
105 _value: unsafe { &*self.value.get() },
106 _borrow: b,
107 },
108 None => self.panic("mutably borrowed"),
109 }
110 }
111
112 #[cfg_attr(debug_assertions, inline(never))]
121 pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
122 match BorrowRefMut::new(&self.borrow) {
123 Some(b) => RefMut {
124 _value: unsafe { &mut *self.value.get() },
125 _borrow: b,
126 },
127 None => self.panic("borrowed"),
128 }
129 }
130
131 #[cfg(not(debug_assertions))]
132 fn panic(&self, msg: &str) -> ! {
133 panic!("RefCell<T> already {}", msg)
134 }
135
136 #[cfg(debug_assertions)]
137 #[allow(unused_must_use)]
138 fn panic(&self, msg: &str) -> ! {
139 let mut msg = format!("RefCell<T> already {}", msg);
140 let locations = self.borrow.locations.borrow();
141 if locations.len() > 0 {
142 msg.push_str("\ncurrent active borrows: \n");
143 for b in locations.iter() {
144 msg.push_str(&format!("-------------------------\n{:?}\n", b));
145 }
146 msg.push_str("\n\n");
147 }
148 panic!(msg)
149 }
150}
151
152#[cfg(not(debug_assertions))]
153impl BorrowFlag {
154 #[inline]
155 fn new() -> BorrowFlag {
156 BorrowFlag { flag: Cell::new(UNUSED) }
157 }
158
159 #[inline]
160 fn push(&self, _caller: Location) {}
161
162 #[inline]
163 fn pop(&self) {}
164}
165
166#[cfg(debug_assertions)]
167impl BorrowFlag {
168 fn new() -> BorrowFlag {
169 BorrowFlag {
170 flag: Cell::new(UNUSED),
171 locations: StdRefCell::new(Vec::new()),
172 }
173 }
174
175 fn push(&self, caller: Location) {
176 self.locations.borrow_mut().push(caller);
177 }
178
179 fn pop(&self) {
180 self.locations.borrow_mut().pop();
181 }
182}
183
184#[cfg(not(debug_assertions))]
185#[inline]
186fn get_caller() -> Location {}
187
188#[inline(never)]
189#[cfg(debug_assertions)]
190fn get_caller() -> Location {
191 backtrace::Backtrace::new()
192}
193
194unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
195
196impl<T: Clone> Clone for RefCell<T> {
197 #[inline]
198 fn clone(&self) -> RefCell<T> {
199 RefCell::new(self.borrow().clone())
200 }
201}
202
203impl<T:Default> Default for RefCell<T> {
204 #[inline]
205 fn default() -> RefCell<T> {
206 RefCell::new(Default::default())
207 }
208}
209
210
211impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> {
212 #[inline]
213 fn eq(&self, other: &RefCell<T>) -> bool {
214 *self.borrow() == *other.borrow()
215 }
216}
217
218impl<T: ?Sized + Eq> Eq for RefCell<T> {}
219
220struct BorrowRef<'b> {
221 borrow: &'b BorrowFlag,
222}
223
224impl<'b> BorrowRef<'b> {
225 #[cfg_attr(debug_assertions, inline(never))]
226 #[cfg_attr(not(debug_assertions), inline)]
227 fn new(borrow: &'b BorrowFlag) -> Option<BorrowRef<'b>> {
228 let flag = borrow.flag.get();
229 if flag == WRITING { return None }
230 borrow.flag.set(flag + 1);
231 borrow.push(get_caller());
232 Some(BorrowRef { borrow: borrow })
233 }
234}
235
236impl<'b> Drop for BorrowRef<'b> {
237 #[inline]
238 fn drop(&mut self) {
239 let flag = self.borrow.flag.get();
240 debug_assert!(flag != WRITING && flag != UNUSED);
241 self.borrow.flag.set(flag - 1);
242 self.borrow.pop();
243 }
244}
245
246pub struct Ref<'b, T: ?Sized + 'b> {
252 _value: &'b T,
255 _borrow: BorrowRef<'b>,
256}
257
258
259impl<'b, T: ?Sized> Deref for Ref<'b, T> {
260 type Target = T;
261 fn deref(&self) -> &T {
262 self._value
263 }
264}
265
266struct BorrowRefMut<'b> {
267 borrow: &'b BorrowFlag,
268}
269
270impl<'b> BorrowRefMut<'b> {
271 #[cfg_attr(debug_assertions, inline(never))]
272 #[cfg_attr(not(debug_assertions), inline)]
273 fn new(borrow: &'b BorrowFlag) -> Option<BorrowRefMut<'b>> {
274 if borrow.flag.get() != UNUSED { return None }
275 borrow.flag.set(WRITING);
276 borrow.push(get_caller());
277 Some(BorrowRefMut { borrow: borrow })
278 }
279}
280
281impl<'b> Drop for BorrowRefMut<'b> {
282 #[inline]
283 fn drop(&mut self) {
284 debug_assert!(self.borrow.flag.get() == WRITING);
285 self.borrow.flag.set(UNUSED);
286 self.borrow.pop();
287 }
288}
289
290pub struct RefMut<'b, T: ?Sized + 'b> {
292 _value: &'b mut T,
295 _borrow: BorrowRefMut<'b>,
296}
297
298
299impl<'b, T: ?Sized> Deref for RefMut<'b, T> {
300 type Target = T;
301 fn deref(&self) -> &T {
302 self._value
303 }
304}
305
306impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
307 fn deref_mut(&mut self) -> &mut T {
308 self._value
309 }
310}
311
312#[cfg(test)]
313mod tests {
314 use super::RefCell;
315
316 #[test]
317 fn ok_borrows() {
318 let a = RefCell::new(2);
319 let b = a.borrow();
320 let c = a.borrow();
321 assert_eq!(*b, 2);
322 assert_eq!(*c, 2);
323 drop((b, c));
324
325 let mut b = a.borrow_mut();
326 assert_eq!(*b, 2);
327 *b = 4;
328 drop(b);
329
330 assert_eq!(*a.borrow(), 4);
331 }
332
333 #[should_panic]
334 #[test]
335 fn bad_borrow_mut() {
336 let a = RefCell::new(2);
337 let _a = a.borrow();
338 a.borrow_mut();
339 }
340
341 #[should_panic]
342 #[test]
343 fn bad_borrow() {
344 let a = RefCell::new(2);
345 let _a = a.borrow_mut();
346 a.borrow();
347 }
348}