]>
Commit | Line | Data |
---|---|---|
85aaf69f | 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
1a4d82fc JJ |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! Shareable mutable containers. | |
12 | //! | |
85aaf69f SL |
13 | //! Values of the `Cell<T>` and `RefCell<T>` types may be mutated through shared references (i.e. |
14 | //! the common `&T` type), whereas most Rust types can only be mutated through unique (`&mut T`) | |
15 | //! references. We say that `Cell<T>` and `RefCell<T>` provide 'interior mutability', in contrast | |
16 | //! with typical Rust types that exhibit 'inherited mutability'. | |
1a4d82fc | 17 | //! |
85aaf69f SL |
18 | //! Cell types come in two flavors: `Cell<T>` and `RefCell<T>`. `Cell<T>` provides `get` and `set` |
19 | //! methods that change the interior value with a single method call. `Cell<T>` though is only | |
20 | //! compatible with types that implement `Copy`. For other types, one must use the `RefCell<T>` | |
21 | //! type, acquiring a write lock before mutating. | |
1a4d82fc | 22 | //! |
85aaf69f SL |
23 | //! `RefCell<T>` uses Rust's lifetimes to implement 'dynamic borrowing', a process whereby one can |
24 | //! claim temporary, exclusive, mutable access to the inner value. Borrows for `RefCell<T>`s are | |
25 | //! tracked 'at runtime', unlike Rust's native reference types which are entirely tracked | |
26 | //! statically, at compile time. Because `RefCell<T>` borrows are dynamic it is possible to attempt | |
bd371182 AL |
27 | //! to borrow a value that is already mutably borrowed; when this happens it results in thread |
28 | //! panic. | |
1a4d82fc JJ |
29 | //! |
30 | //! # When to choose interior mutability | |
31 | //! | |
85aaf69f SL |
32 | //! The more common inherited mutability, where one must have unique access to mutate a value, is |
33 | //! one of the key language elements that enables Rust to reason strongly about pointer aliasing, | |
34 | //! statically preventing crash bugs. Because of that, inherited mutability is preferred, and | |
35 | //! interior mutability is something of a last resort. Since cell types enable mutation where it | |
36 | //! would otherwise be disallowed though, there are occasions when interior mutability might be | |
37 | //! appropriate, or even *must* be used, e.g. | |
1a4d82fc | 38 | //! |
c1a9b12d | 39 | //! * Introducing mutability 'inside' of something immutable |
1a4d82fc | 40 | //! * Implementation details of logically-immutable methods. |
62682a34 | 41 | //! * Mutating implementations of `Clone`. |
1a4d82fc | 42 | //! |
c1a9b12d | 43 | //! ## Introducing mutability 'inside' of something immutable |
1a4d82fc | 44 | //! |
c1a9b12d | 45 | //! Many shared smart pointer types, including `Rc<T>` and `Arc<T>`, provide containers that can be |
85aaf69f | 46 | //! cloned and shared between multiple parties. Because the contained values may be |
c1a9b12d SL |
47 | //! multiply-aliased, they can only be borrowed with `&`, not `&mut`. Without cells it would be |
48 | //! impossible to mutate data inside of these smart pointers at all. | |
1a4d82fc | 49 | //! |
85aaf69f SL |
50 | //! It's very common then to put a `RefCell<T>` inside shared pointer types to reintroduce |
51 | //! mutability: | |
1a4d82fc JJ |
52 | //! |
53 | //! ``` | |
54 | //! use std::collections::HashMap; | |
55 | //! use std::cell::RefCell; | |
56 | //! use std::rc::Rc; | |
57 | //! | |
58 | //! fn main() { | |
59 | //! let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new())); | |
85aaf69f SL |
60 | //! shared_map.borrow_mut().insert("africa", 92388); |
61 | //! shared_map.borrow_mut().insert("kyoto", 11837); | |
62 | //! shared_map.borrow_mut().insert("piccadilly", 11826); | |
63 | //! shared_map.borrow_mut().insert("marbles", 38); | |
1a4d82fc JJ |
64 | //! } |
65 | //! ``` | |
66 | //! | |
85aaf69f | 67 | //! Note that this example uses `Rc<T>` and not `Arc<T>`. `RefCell<T>`s are for single-threaded |
c1a9b12d SL |
68 | //! scenarios. Consider using `RwLock<T>` or `Mutex<T>` if you need shared mutability in a |
69 | //! multi-threaded situation. | |
85aaf69f | 70 | //! |
1a4d82fc JJ |
71 | //! ## Implementation details of logically-immutable methods |
72 | //! | |
85aaf69f SL |
73 | //! Occasionally it may be desirable not to expose in an API that there is mutation happening |
74 | //! "under the hood". This may be because logically the operation is immutable, but e.g. caching | |
75 | //! forces the implementation to perform mutation; or because you must employ mutation to implement | |
76 | //! a trait method that was originally defined to take `&self`. | |
1a4d82fc JJ |
77 | //! |
78 | //! ``` | |
92a42be0 | 79 | //! # #![allow(dead_code)] |
1a4d82fc JJ |
80 | //! use std::cell::RefCell; |
81 | //! | |
82 | //! struct Graph { | |
85aaf69f SL |
83 | //! edges: Vec<(i32, i32)>, |
84 | //! span_tree_cache: RefCell<Option<Vec<(i32, i32)>>> | |
1a4d82fc JJ |
85 | //! } |
86 | //! | |
87 | //! impl Graph { | |
85aaf69f | 88 | //! fn minimum_spanning_tree(&self) -> Vec<(i32, i32)> { |
1a4d82fc JJ |
89 | //! // Create a new scope to contain the lifetime of the |
90 | //! // dynamic borrow | |
91 | //! { | |
92 | //! // Take a reference to the inside of cache cell | |
93 | //! let mut cache = self.span_tree_cache.borrow_mut(); | |
94 | //! if cache.is_some() { | |
95 | //! return cache.as_ref().unwrap().clone(); | |
96 | //! } | |
97 | //! | |
98 | //! let span_tree = self.calc_span_tree(); | |
99 | //! *cache = Some(span_tree); | |
100 | //! } | |
101 | //! | |
102 | //! // Recursive call to return the just-cached value. | |
103 | //! // Note that if we had not let the previous borrow | |
104 | //! // of the cache fall out of scope then the subsequent | |
bd371182 | 105 | //! // recursive borrow would cause a dynamic thread panic. |
1a4d82fc JJ |
106 | //! // This is the major hazard of using `RefCell`. |
107 | //! self.minimum_spanning_tree() | |
108 | //! } | |
85aaf69f | 109 | //! # fn calc_span_tree(&self) -> Vec<(i32, i32)> { vec![] } |
1a4d82fc | 110 | //! } |
1a4d82fc JJ |
111 | //! ``` |
112 | //! | |
62682a34 | 113 | //! ## Mutating implementations of `Clone` |
1a4d82fc | 114 | //! |
85aaf69f SL |
115 | //! This is simply a special - but common - case of the previous: hiding mutability for operations |
116 | //! that appear to be immutable. The `clone` method is expected to not change the source value, and | |
117 | //! is declared to take `&self`, not `&mut self`. Therefore any mutation that happens in the | |
118 | //! `clone` method must use cell types. For example, `Rc<T>` maintains its reference counts within a | |
119 | //! `Cell<T>`. | |
1a4d82fc JJ |
120 | //! |
121 | //! ``` | |
122 | //! use std::cell::Cell; | |
123 | //! | |
124 | //! struct Rc<T> { | |
125 | //! ptr: *mut RcBox<T> | |
126 | //! } | |
127 | //! | |
128 | //! struct RcBox<T> { | |
92a42be0 | 129 | //! # #[allow(dead_code)] |
1a4d82fc | 130 | //! value: T, |
85aaf69f | 131 | //! refcount: Cell<usize> |
1a4d82fc JJ |
132 | //! } |
133 | //! | |
134 | //! impl<T> Clone for Rc<T> { | |
135 | //! fn clone(&self) -> Rc<T> { | |
136 | //! unsafe { | |
137 | //! (*self.ptr).refcount.set((*self.ptr).refcount.get() + 1); | |
138 | //! Rc { ptr: self.ptr } | |
139 | //! } | |
140 | //! } | |
141 | //! } | |
142 | //! ``` | |
143 | //! | |
1a4d82fc | 144 | |
85aaf69f | 145 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
146 | |
147 | use clone::Clone; | |
62682a34 | 148 | use cmp::{PartialEq, Eq}; |
1a4d82fc | 149 | use default::Default; |
54a0048b SL |
150 | use marker::{Copy, Send, Sync, Sized, Unsize}; |
151 | use ops::{Deref, DerefMut, Drop, FnOnce, CoerceUnsized}; | |
1a4d82fc JJ |
152 | use option::Option; |
153 | use option::Option::{None, Some}; | |
154 | ||
155 | /// A mutable memory location that admits only `Copy` data. | |
85aaf69f SL |
156 | /// |
157 | /// See the [module-level documentation](index.html) for more. | |
158 | #[stable(feature = "rust1", since = "1.0.0")] | |
1a4d82fc JJ |
159 | pub struct Cell<T> { |
160 | value: UnsafeCell<T>, | |
161 | } | |
162 | ||
163 | impl<T:Copy> Cell<T> { | |
164 | /// Creates a new `Cell` containing the given value. | |
85aaf69f SL |
165 | /// |
166 | /// # Examples | |
167 | /// | |
168 | /// ``` | |
169 | /// use std::cell::Cell; | |
170 | /// | |
171 | /// let c = Cell::new(5); | |
172 | /// ``` | |
173 | #[stable(feature = "rust1", since = "1.0.0")] | |
c34b1796 | 174 | #[inline] |
62682a34 | 175 | pub const fn new(value: T) -> Cell<T> { |
1a4d82fc JJ |
176 | Cell { |
177 | value: UnsafeCell::new(value), | |
178 | } | |
179 | } | |
180 | ||
181 | /// Returns a copy of the contained value. | |
85aaf69f SL |
182 | /// |
183 | /// # Examples | |
184 | /// | |
185 | /// ``` | |
186 | /// use std::cell::Cell; | |
187 | /// | |
188 | /// let c = Cell::new(5); | |
189 | /// | |
190 | /// let five = c.get(); | |
191 | /// ``` | |
1a4d82fc | 192 | #[inline] |
85aaf69f | 193 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
194 | pub fn get(&self) -> T { |
195 | unsafe{ *self.value.get() } | |
196 | } | |
197 | ||
198 | /// Sets the contained value. | |
85aaf69f SL |
199 | /// |
200 | /// # Examples | |
201 | /// | |
202 | /// ``` | |
203 | /// use std::cell::Cell; | |
204 | /// | |
205 | /// let c = Cell::new(5); | |
206 | /// | |
207 | /// c.set(10); | |
208 | /// ``` | |
1a4d82fc | 209 | #[inline] |
85aaf69f | 210 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
211 | pub fn set(&self, value: T) { |
212 | unsafe { | |
213 | *self.value.get() = value; | |
214 | } | |
215 | } | |
216 | ||
62682a34 | 217 | /// Returns a reference to the underlying `UnsafeCell`. |
1a4d82fc | 218 | /// |
85aaf69f SL |
219 | /// # Examples |
220 | /// | |
221 | /// ``` | |
c1a9b12d SL |
222 | /// #![feature(as_unsafe_cell)] |
223 | /// | |
85aaf69f SL |
224 | /// use std::cell::Cell; |
225 | /// | |
226 | /// let c = Cell::new(5); | |
227 | /// | |
54a0048b | 228 | /// let uc = c.as_unsafe_cell(); |
85aaf69f | 229 | /// ``` |
1a4d82fc | 230 | #[inline] |
e9174d1e | 231 | #[unstable(feature = "as_unsafe_cell", issue = "27708")] |
54a0048b | 232 | pub fn as_unsafe_cell(&self) -> &UnsafeCell<T> { |
1a4d82fc JJ |
233 | &self.value |
234 | } | |
235 | } | |
236 | ||
85aaf69f | 237 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
238 | unsafe impl<T> Send for Cell<T> where T: Send {} |
239 | ||
54a0048b SL |
240 | #[stable(feature = "rust1", since = "1.0.0")] |
241 | impl<T> !Sync for Cell<T> {} | |
242 | ||
85aaf69f | 243 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 244 | impl<T:Copy> Clone for Cell<T> { |
c34b1796 | 245 | #[inline] |
1a4d82fc JJ |
246 | fn clone(&self) -> Cell<T> { |
247 | Cell::new(self.get()) | |
248 | } | |
249 | } | |
250 | ||
85aaf69f | 251 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 252 | impl<T:Default + Copy> Default for Cell<T> { |
c34b1796 | 253 | #[inline] |
1a4d82fc JJ |
254 | fn default() -> Cell<T> { |
255 | Cell::new(Default::default()) | |
256 | } | |
257 | } | |
258 | ||
85aaf69f | 259 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 260 | impl<T:PartialEq + Copy> PartialEq for Cell<T> { |
c34b1796 | 261 | #[inline] |
1a4d82fc JJ |
262 | fn eq(&self, other: &Cell<T>) -> bool { |
263 | self.get() == other.get() | |
264 | } | |
265 | } | |
266 | ||
62682a34 SL |
267 | #[stable(feature = "cell_eq", since = "1.2.0")] |
268 | impl<T:Eq + Copy> Eq for Cell<T> {} | |
269 | ||
1a4d82fc | 270 | /// A mutable memory location with dynamically checked borrow rules |
85aaf69f SL |
271 | /// |
272 | /// See the [module-level documentation](index.html) for more. | |
273 | #[stable(feature = "rust1", since = "1.0.0")] | |
d9579d0f | 274 | pub struct RefCell<T: ?Sized> { |
1a4d82fc | 275 | borrow: Cell<BorrowFlag>, |
d9579d0f | 276 | value: UnsafeCell<T>, |
1a4d82fc JJ |
277 | } |
278 | ||
85aaf69f | 279 | /// An enumeration of values returned from the `state` method on a `RefCell<T>`. |
62682a34 | 280 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
e9174d1e | 281 | #[unstable(feature = "borrow_state", issue = "27733")] |
85aaf69f SL |
282 | pub enum BorrowState { |
283 | /// The cell is currently being read, there is at least one active `borrow`. | |
284 | Reading, | |
285 | /// The cell is currently being written to, there is an active `borrow_mut`. | |
286 | Writing, | |
287 | /// There are no outstanding borrows on this cell. | |
288 | Unused, | |
289 | } | |
290 | ||
1a4d82fc | 291 | // Values [1, MAX-1] represent the number of `Ref` active |
85aaf69f SL |
292 | // (will not outgrow its range since `usize` is the size of the address space) |
293 | type BorrowFlag = usize; | |
1a4d82fc | 294 | const UNUSED: BorrowFlag = 0; |
c34b1796 | 295 | const WRITING: BorrowFlag = !0; |
1a4d82fc JJ |
296 | |
297 | impl<T> RefCell<T> { | |
85aaf69f SL |
298 | /// Creates a new `RefCell` containing `value`. |
299 | /// | |
300 | /// # Examples | |
301 | /// | |
302 | /// ``` | |
303 | /// use std::cell::RefCell; | |
304 | /// | |
305 | /// let c = RefCell::new(5); | |
306 | /// ``` | |
307 | #[stable(feature = "rust1", since = "1.0.0")] | |
c34b1796 | 308 | #[inline] |
62682a34 | 309 | pub const fn new(value: T) -> RefCell<T> { |
1a4d82fc JJ |
310 | RefCell { |
311 | value: UnsafeCell::new(value), | |
312 | borrow: Cell::new(UNUSED), | |
313 | } | |
314 | } | |
315 | ||
316 | /// Consumes the `RefCell`, returning the wrapped value. | |
85aaf69f SL |
317 | /// |
318 | /// # Examples | |
319 | /// | |
320 | /// ``` | |
321 | /// use std::cell::RefCell; | |
322 | /// | |
323 | /// let c = RefCell::new(5); | |
324 | /// | |
325 | /// let five = c.into_inner(); | |
326 | /// ``` | |
327 | #[stable(feature = "rust1", since = "1.0.0")] | |
c34b1796 | 328 | #[inline] |
1a4d82fc JJ |
329 | pub fn into_inner(self) -> T { |
330 | // Since this function takes `self` (the `RefCell`) by value, the | |
331 | // compiler statically verifies that it is not currently borrowed. | |
332 | // Therefore the following assertion is just a `debug_assert!`. | |
333 | debug_assert!(self.borrow.get() == UNUSED); | |
334 | unsafe { self.value.into_inner() } | |
335 | } | |
d9579d0f | 336 | } |
1a4d82fc | 337 | |
d9579d0f | 338 | impl<T: ?Sized> RefCell<T> { |
85aaf69f SL |
339 | /// Query the current state of this `RefCell` |
340 | /// | |
341 | /// The returned value can be dispatched on to determine if a call to | |
342 | /// `borrow` or `borrow_mut` would succeed. | |
e9174d1e | 343 | #[unstable(feature = "borrow_state", issue = "27733")] |
c34b1796 | 344 | #[inline] |
85aaf69f SL |
345 | pub fn borrow_state(&self) -> BorrowState { |
346 | match self.borrow.get() { | |
347 | WRITING => BorrowState::Writing, | |
348 | UNUSED => BorrowState::Unused, | |
349 | _ => BorrowState::Reading, | |
350 | } | |
351 | } | |
352 | ||
1a4d82fc JJ |
353 | /// Immutably borrows the wrapped value. |
354 | /// | |
355 | /// The borrow lasts until the returned `Ref` exits scope. Multiple | |
356 | /// immutable borrows can be taken out at the same time. | |
357 | /// | |
358 | /// # Panics | |
359 | /// | |
360 | /// Panics if the value is currently mutably borrowed. | |
85aaf69f SL |
361 | /// |
362 | /// # Examples | |
363 | /// | |
364 | /// ``` | |
365 | /// use std::cell::RefCell; | |
366 | /// | |
367 | /// let c = RefCell::new(5); | |
368 | /// | |
369 | /// let borrowed_five = c.borrow(); | |
370 | /// let borrowed_five2 = c.borrow(); | |
371 | /// ``` | |
372 | /// | |
373 | /// An example of panic: | |
374 | /// | |
375 | /// ``` | |
376 | /// use std::cell::RefCell; | |
377 | /// use std::thread; | |
378 | /// | |
379 | /// let result = thread::spawn(move || { | |
380 | /// let c = RefCell::new(5); | |
381 | /// let m = c.borrow_mut(); | |
382 | /// | |
383 | /// let b = c.borrow(); // this causes a panic | |
384 | /// }).join(); | |
385 | /// | |
386 | /// assert!(result.is_err()); | |
387 | /// ``` | |
388 | #[stable(feature = "rust1", since = "1.0.0")] | |
c34b1796 | 389 | #[inline] |
e9174d1e | 390 | pub fn borrow(&self) -> Ref<T> { |
85aaf69f SL |
391 | match BorrowRef::new(&self.borrow) { |
392 | Some(b) => Ref { | |
54a0048b SL |
393 | value: unsafe { &*self.value.get() }, |
394 | borrow: b, | |
85aaf69f SL |
395 | }, |
396 | None => panic!("RefCell<T> already mutably borrowed"), | |
1a4d82fc JJ |
397 | } |
398 | } | |
399 | ||
1a4d82fc JJ |
400 | /// Mutably borrows the wrapped value. |
401 | /// | |
402 | /// The borrow lasts until the returned `RefMut` exits scope. The value | |
403 | /// cannot be borrowed while this borrow is active. | |
404 | /// | |
405 | /// # Panics | |
406 | /// | |
407 | /// Panics if the value is currently borrowed. | |
85aaf69f SL |
408 | /// |
409 | /// # Examples | |
410 | /// | |
411 | /// ``` | |
412 | /// use std::cell::RefCell; | |
413 | /// | |
414 | /// let c = RefCell::new(5); | |
415 | /// | |
7453a54e SL |
416 | /// *c.borrow_mut() = 7; |
417 | /// | |
418 | /// assert_eq!(*c.borrow(), 7); | |
85aaf69f SL |
419 | /// ``` |
420 | /// | |
421 | /// An example of panic: | |
422 | /// | |
423 | /// ``` | |
424 | /// use std::cell::RefCell; | |
425 | /// use std::thread; | |
426 | /// | |
427 | /// let result = thread::spawn(move || { | |
428 | /// let c = RefCell::new(5); | |
bd371182 | 429 | /// let m = c.borrow(); |
85aaf69f SL |
430 | /// |
431 | /// let b = c.borrow_mut(); // this causes a panic | |
432 | /// }).join(); | |
433 | /// | |
434 | /// assert!(result.is_err()); | |
435 | /// ``` | |
436 | #[stable(feature = "rust1", since = "1.0.0")] | |
c34b1796 | 437 | #[inline] |
e9174d1e | 438 | pub fn borrow_mut(&self) -> RefMut<T> { |
85aaf69f SL |
439 | match BorrowRefMut::new(&self.borrow) { |
440 | Some(b) => RefMut { | |
54a0048b SL |
441 | value: unsafe { &mut *self.value.get() }, |
442 | borrow: b, | |
85aaf69f SL |
443 | }, |
444 | None => panic!("RefCell<T> already borrowed"), | |
1a4d82fc JJ |
445 | } |
446 | } | |
447 | ||
62682a34 | 448 | /// Returns a reference to the underlying `UnsafeCell`. |
1a4d82fc JJ |
449 | /// |
450 | /// This can be used to circumvent `RefCell`'s safety checks. | |
451 | /// | |
452 | /// This function is `unsafe` because `UnsafeCell`'s field is public. | |
453 | #[inline] | |
e9174d1e SL |
454 | #[unstable(feature = "as_unsafe_cell", issue = "27708")] |
455 | pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> { | |
1a4d82fc JJ |
456 | &self.value |
457 | } | |
458 | } | |
459 | ||
85aaf69f | 460 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 461 | unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {} |
1a4d82fc | 462 | |
54a0048b SL |
463 | #[stable(feature = "rust1", since = "1.0.0")] |
464 | impl<T: ?Sized> !Sync for RefCell<T> {} | |
465 | ||
85aaf69f | 466 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 467 | impl<T: Clone> Clone for RefCell<T> { |
c34b1796 | 468 | #[inline] |
1a4d82fc JJ |
469 | fn clone(&self) -> RefCell<T> { |
470 | RefCell::new(self.borrow().clone()) | |
471 | } | |
472 | } | |
473 | ||
85aaf69f | 474 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 475 | impl<T:Default> Default for RefCell<T> { |
c34b1796 | 476 | #[inline] |
1a4d82fc JJ |
477 | fn default() -> RefCell<T> { |
478 | RefCell::new(Default::default()) | |
479 | } | |
480 | } | |
481 | ||
85aaf69f | 482 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 483 | impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> { |
c34b1796 | 484 | #[inline] |
1a4d82fc JJ |
485 | fn eq(&self, other: &RefCell<T>) -> bool { |
486 | *self.borrow() == *other.borrow() | |
487 | } | |
488 | } | |
489 | ||
62682a34 SL |
490 | #[stable(feature = "cell_eq", since = "1.2.0")] |
491 | impl<T: ?Sized + Eq> Eq for RefCell<T> {} | |
492 | ||
1a4d82fc | 493 | struct BorrowRef<'b> { |
54a0048b | 494 | borrow: &'b Cell<BorrowFlag>, |
1a4d82fc JJ |
495 | } |
496 | ||
497 | impl<'b> BorrowRef<'b> { | |
c34b1796 | 498 | #[inline] |
1a4d82fc JJ |
499 | fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> { |
500 | match borrow.get() { | |
501 | WRITING => None, | |
502 | b => { | |
503 | borrow.set(b + 1); | |
54a0048b | 504 | Some(BorrowRef { borrow: borrow }) |
1a4d82fc JJ |
505 | }, |
506 | } | |
507 | } | |
508 | } | |
509 | ||
1a4d82fc | 510 | impl<'b> Drop for BorrowRef<'b> { |
c34b1796 | 511 | #[inline] |
1a4d82fc | 512 | fn drop(&mut self) { |
54a0048b | 513 | let borrow = self.borrow.get(); |
1a4d82fc | 514 | debug_assert!(borrow != WRITING && borrow != UNUSED); |
54a0048b | 515 | self.borrow.set(borrow - 1); |
1a4d82fc JJ |
516 | } |
517 | } | |
518 | ||
519 | impl<'b> Clone for BorrowRef<'b> { | |
c34b1796 | 520 | #[inline] |
1a4d82fc JJ |
521 | fn clone(&self) -> BorrowRef<'b> { |
522 | // Since this Ref exists, we know the borrow flag | |
523 | // is not set to WRITING. | |
54a0048b | 524 | let borrow = self.borrow.get(); |
1a4d82fc | 525 | debug_assert!(borrow != WRITING && borrow != UNUSED); |
54a0048b SL |
526 | self.borrow.set(borrow + 1); |
527 | BorrowRef { borrow: self.borrow } | |
1a4d82fc JJ |
528 | } |
529 | } | |
530 | ||
531 | /// Wraps a borrowed reference to a value in a `RefCell` box. | |
85aaf69f SL |
532 | /// A wrapper type for an immutably borrowed value from a `RefCell<T>`. |
533 | /// | |
534 | /// See the [module-level documentation](index.html) for more. | |
535 | #[stable(feature = "rust1", since = "1.0.0")] | |
d9579d0f | 536 | pub struct Ref<'b, T: ?Sized + 'b> { |
54a0048b SL |
537 | value: &'b T, |
538 | borrow: BorrowRef<'b>, | |
1a4d82fc JJ |
539 | } |
540 | ||
85aaf69f | 541 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 542 | impl<'b, T: ?Sized> Deref for Ref<'b, T> { |
1a4d82fc JJ |
543 | type Target = T; |
544 | ||
545 | #[inline] | |
e9174d1e | 546 | fn deref(&self) -> &T { |
54a0048b | 547 | self.value |
1a4d82fc JJ |
548 | } |
549 | } | |
550 | ||
62682a34 SL |
551 | impl<'b, T: ?Sized> Ref<'b, T> { |
552 | /// Copies a `Ref`. | |
553 | /// | |
554 | /// The `RefCell` is already immutably borrowed, so this cannot fail. | |
555 | /// | |
556 | /// This is an associated function that needs to be used as | |
557 | /// `Ref::clone(...)`. A `Clone` implementation or a method would interfere | |
558 | /// with the widespread use of `r.borrow().clone()` to clone the contents of | |
559 | /// a `RefCell`. | |
560 | #[unstable(feature = "cell_extras", | |
e9174d1e SL |
561 | reason = "likely to be moved to a method, pending language changes", |
562 | issue = "27746")] | |
62682a34 SL |
563 | #[inline] |
564 | pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> { | |
565 | Ref { | |
54a0048b SL |
566 | value: orig.value, |
567 | borrow: orig.borrow.clone(), | |
62682a34 SL |
568 | } |
569 | } | |
570 | ||
571 | /// Make a new `Ref` for a component of the borrowed data. | |
572 | /// | |
573 | /// The `RefCell` is already immutably borrowed, so this cannot fail. | |
574 | /// | |
575 | /// This is an associated function that needs to be used as `Ref::map(...)`. | |
576 | /// A method would interfere with methods of the same name on the contents | |
577 | /// of a `RefCell` used through `Deref`. | |
578 | /// | |
579 | /// # Example | |
580 | /// | |
581 | /// ``` | |
62682a34 SL |
582 | /// use std::cell::{RefCell, Ref}; |
583 | /// | |
584 | /// let c = RefCell::new((5, 'b')); | |
585 | /// let b1: Ref<(u32, char)> = c.borrow(); | |
586 | /// let b2: Ref<u32> = Ref::map(b1, |t| &t.0); | |
587 | /// assert_eq!(*b2, 5) | |
588 | /// ``` | |
7453a54e | 589 | #[stable(feature = "cell_map", since = "1.8.0")] |
62682a34 SL |
590 | #[inline] |
591 | pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U> | |
592 | where F: FnOnce(&T) -> &U | |
593 | { | |
594 | Ref { | |
54a0048b SL |
595 | value: f(orig.value), |
596 | borrow: orig.borrow, | |
62682a34 SL |
597 | } |
598 | } | |
599 | ||
b039eaaf | 600 | /// Make a new `Ref` for an optional component of the borrowed data, e.g. an |
62682a34 SL |
601 | /// enum variant. |
602 | /// | |
603 | /// The `RefCell` is already immutably borrowed, so this cannot fail. | |
604 | /// | |
605 | /// This is an associated function that needs to be used as | |
606 | /// `Ref::filter_map(...)`. A method would interfere with methods of the | |
607 | /// same name on the contents of a `RefCell` used through `Deref`. | |
608 | /// | |
609 | /// # Example | |
610 | /// | |
611 | /// ``` | |
612 | /// # #![feature(cell_extras)] | |
613 | /// use std::cell::{RefCell, Ref}; | |
614 | /// | |
615 | /// let c = RefCell::new(Ok(5)); | |
616 | /// let b1: Ref<Result<u32, ()>> = c.borrow(); | |
617 | /// let b2: Ref<u32> = Ref::filter_map(b1, |o| o.as_ref().ok()).unwrap(); | |
618 | /// assert_eq!(*b2, 5) | |
619 | /// ``` | |
e9174d1e SL |
620 | #[unstable(feature = "cell_extras", reason = "recently added", |
621 | issue = "27746")] | |
54a0048b SL |
622 | #[rustc_deprecated(since = "1.8.0", reason = "can be built on `Ref::map`: \ |
623 | https://crates.io/crates/ref_filter_map")] | |
62682a34 SL |
624 | #[inline] |
625 | pub fn filter_map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Option<Ref<'b, U>> | |
626 | where F: FnOnce(&T) -> Option<&U> | |
627 | { | |
54a0048b SL |
628 | f(orig.value).map(move |new| Ref { |
629 | value: new, | |
630 | borrow: orig.borrow, | |
62682a34 SL |
631 | }) |
632 | } | |
633 | } | |
634 | ||
54a0048b SL |
635 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
636 | impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {} | |
637 | ||
62682a34 SL |
638 | impl<'b, T: ?Sized> RefMut<'b, T> { |
639 | /// Make a new `RefMut` for a component of the borrowed data, e.g. an enum | |
640 | /// variant. | |
641 | /// | |
642 | /// The `RefCell` is already mutably borrowed, so this cannot fail. | |
643 | /// | |
644 | /// This is an associated function that needs to be used as | |
645 | /// `RefMut::map(...)`. A method would interfere with methods of the same | |
646 | /// name on the contents of a `RefCell` used through `Deref`. | |
647 | /// | |
648 | /// # Example | |
649 | /// | |
650 | /// ``` | |
62682a34 SL |
651 | /// use std::cell::{RefCell, RefMut}; |
652 | /// | |
653 | /// let c = RefCell::new((5, 'b')); | |
654 | /// { | |
655 | /// let b1: RefMut<(u32, char)> = c.borrow_mut(); | |
656 | /// let mut b2: RefMut<u32> = RefMut::map(b1, |t| &mut t.0); | |
657 | /// assert_eq!(*b2, 5); | |
658 | /// *b2 = 42; | |
659 | /// } | |
660 | /// assert_eq!(*c.borrow(), (42, 'b')); | |
661 | /// ``` | |
7453a54e | 662 | #[stable(feature = "cell_map", since = "1.8.0")] |
62682a34 SL |
663 | #[inline] |
664 | pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U> | |
665 | where F: FnOnce(&mut T) -> &mut U | |
666 | { | |
667 | RefMut { | |
54a0048b SL |
668 | value: f(orig.value), |
669 | borrow: orig.borrow, | |
62682a34 SL |
670 | } |
671 | } | |
672 | ||
b039eaaf | 673 | /// Make a new `RefMut` for an optional component of the borrowed data, e.g. |
62682a34 SL |
674 | /// an enum variant. |
675 | /// | |
676 | /// The `RefCell` is already mutably borrowed, so this cannot fail. | |
677 | /// | |
678 | /// This is an associated function that needs to be used as | |
679 | /// `RefMut::filter_map(...)`. A method would interfere with methods of the | |
680 | /// same name on the contents of a `RefCell` used through `Deref`. | |
681 | /// | |
682 | /// # Example | |
683 | /// | |
684 | /// ``` | |
685 | /// # #![feature(cell_extras)] | |
686 | /// use std::cell::{RefCell, RefMut}; | |
687 | /// | |
688 | /// let c = RefCell::new(Ok(5)); | |
689 | /// { | |
690 | /// let b1: RefMut<Result<u32, ()>> = c.borrow_mut(); | |
691 | /// let mut b2: RefMut<u32> = RefMut::filter_map(b1, |o| { | |
692 | /// o.as_mut().ok() | |
693 | /// }).unwrap(); | |
694 | /// assert_eq!(*b2, 5); | |
695 | /// *b2 = 42; | |
696 | /// } | |
697 | /// assert_eq!(*c.borrow(), Ok(42)); | |
698 | /// ``` | |
e9174d1e SL |
699 | #[unstable(feature = "cell_extras", reason = "recently added", |
700 | issue = "27746")] | |
54a0048b SL |
701 | #[rustc_deprecated(since = "1.8.0", reason = "can be built on `RefMut::map`: \ |
702 | https://crates.io/crates/ref_filter_map")] | |
62682a34 SL |
703 | #[inline] |
704 | pub fn filter_map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> Option<RefMut<'b, U>> | |
705 | where F: FnOnce(&mut T) -> Option<&mut U> | |
706 | { | |
54a0048b SL |
707 | let RefMut { value, borrow } = orig; |
708 | f(value).map(move |new| RefMut { | |
709 | value: new, | |
710 | borrow: borrow, | |
62682a34 | 711 | }) |
1a4d82fc JJ |
712 | } |
713 | } | |
714 | ||
715 | struct BorrowRefMut<'b> { | |
54a0048b | 716 | borrow: &'b Cell<BorrowFlag>, |
1a4d82fc JJ |
717 | } |
718 | ||
1a4d82fc | 719 | impl<'b> Drop for BorrowRefMut<'b> { |
c34b1796 | 720 | #[inline] |
1a4d82fc | 721 | fn drop(&mut self) { |
54a0048b | 722 | let borrow = self.borrow.get(); |
1a4d82fc | 723 | debug_assert!(borrow == WRITING); |
54a0048b | 724 | self.borrow.set(UNUSED); |
1a4d82fc JJ |
725 | } |
726 | } | |
727 | ||
728 | impl<'b> BorrowRefMut<'b> { | |
c34b1796 | 729 | #[inline] |
1a4d82fc JJ |
730 | fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> { |
731 | match borrow.get() { | |
732 | UNUSED => { | |
733 | borrow.set(WRITING); | |
54a0048b | 734 | Some(BorrowRefMut { borrow: borrow }) |
1a4d82fc JJ |
735 | }, |
736 | _ => None, | |
737 | } | |
738 | } | |
739 | } | |
740 | ||
85aaf69f SL |
741 | /// A wrapper type for a mutably borrowed value from a `RefCell<T>`. |
742 | /// | |
743 | /// See the [module-level documentation](index.html) for more. | |
744 | #[stable(feature = "rust1", since = "1.0.0")] | |
d9579d0f | 745 | pub struct RefMut<'b, T: ?Sized + 'b> { |
54a0048b SL |
746 | value: &'b mut T, |
747 | borrow: BorrowRefMut<'b>, | |
1a4d82fc JJ |
748 | } |
749 | ||
85aaf69f | 750 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 751 | impl<'b, T: ?Sized> Deref for RefMut<'b, T> { |
1a4d82fc JJ |
752 | type Target = T; |
753 | ||
754 | #[inline] | |
e9174d1e | 755 | fn deref(&self) -> &T { |
54a0048b | 756 | self.value |
1a4d82fc JJ |
757 | } |
758 | } | |
759 | ||
85aaf69f | 760 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 761 | impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> { |
1a4d82fc | 762 | #[inline] |
e9174d1e | 763 | fn deref_mut(&mut self) -> &mut T { |
54a0048b | 764 | self.value |
1a4d82fc JJ |
765 | } |
766 | } | |
767 | ||
54a0048b SL |
768 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
769 | impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {} | |
770 | ||
1a4d82fc JJ |
771 | /// The core primitive for interior mutability in Rust. |
772 | /// | |
85aaf69f SL |
773 | /// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the |
774 | /// wrapped type. Types with an `UnsafeCell<T>` field are considered to have an 'unsafe interior'. | |
775 | /// The `UnsafeCell<T>` type is the only legal way to obtain aliasable data that is considered | |
776 | /// mutable. In general, transmuting an `&T` type into an `&mut T` is considered undefined behavior. | |
1a4d82fc | 777 | /// |
85aaf69f | 778 | /// Types like `Cell<T>` and `RefCell<T>` use this type to wrap their internal data. |
1a4d82fc | 779 | /// |
85aaf69f | 780 | /// # Examples |
1a4d82fc | 781 | /// |
85aaf69f | 782 | /// ``` |
1a4d82fc | 783 | /// use std::cell::UnsafeCell; |
85aaf69f | 784 | /// use std::marker::Sync; |
1a4d82fc | 785 | /// |
92a42be0 | 786 | /// # #[allow(dead_code)] |
1a4d82fc JJ |
787 | /// struct NotThreadSafe<T> { |
788 | /// value: UnsafeCell<T>, | |
1a4d82fc | 789 | /// } |
85aaf69f SL |
790 | /// |
791 | /// unsafe impl<T> Sync for NotThreadSafe<T> {} | |
1a4d82fc | 792 | /// ``` |
d9579d0f | 793 | #[lang = "unsafe_cell"] |
85aaf69f | 794 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 795 | pub struct UnsafeCell<T: ?Sized> { |
e9174d1e | 796 | value: T, |
1a4d82fc JJ |
797 | } |
798 | ||
92a42be0 | 799 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 800 | impl<T: ?Sized> !Sync for UnsafeCell<T> {} |
c34b1796 | 801 | |
1a4d82fc | 802 | impl<T> UnsafeCell<T> { |
9346a6ac | 803 | /// Constructs a new instance of `UnsafeCell` which will wrap the specified |
1a4d82fc JJ |
804 | /// value. |
805 | /// | |
b039eaaf | 806 | /// All access to the inner value through methods is `unsafe`. |
85aaf69f SL |
807 | /// |
808 | /// # Examples | |
809 | /// | |
810 | /// ``` | |
811 | /// use std::cell::UnsafeCell; | |
812 | /// | |
813 | /// let uc = UnsafeCell::new(5); | |
814 | /// ``` | |
815 | #[stable(feature = "rust1", since = "1.0.0")] | |
c34b1796 | 816 | #[inline] |
62682a34 | 817 | pub const fn new(value: T) -> UnsafeCell<T> { |
1a4d82fc JJ |
818 | UnsafeCell { value: value } |
819 | } | |
820 | ||
d9579d0f AL |
821 | /// Unwraps the value. |
822 | /// | |
b039eaaf | 823 | /// # Safety |
d9579d0f | 824 | /// |
62682a34 SL |
825 | /// This function is unsafe because this thread or another thread may currently be |
826 | /// inspecting the inner value. | |
85aaf69f SL |
827 | /// |
828 | /// # Examples | |
829 | /// | |
830 | /// ``` | |
831 | /// use std::cell::UnsafeCell; | |
832 | /// | |
833 | /// let uc = UnsafeCell::new(5); | |
834 | /// | |
d9579d0f | 835 | /// let five = unsafe { uc.into_inner() }; |
85aaf69f | 836 | /// ``` |
1a4d82fc | 837 | #[inline] |
85aaf69f | 838 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 839 | pub unsafe fn into_inner(self) -> T { |
62682a34 SL |
840 | self.value |
841 | } | |
d9579d0f | 842 | } |
1a4d82fc | 843 | |
d9579d0f AL |
844 | impl<T: ?Sized> UnsafeCell<T> { |
845 | /// Gets a mutable pointer to the wrapped value. | |
85aaf69f SL |
846 | /// |
847 | /// # Examples | |
848 | /// | |
849 | /// ``` | |
850 | /// use std::cell::UnsafeCell; | |
851 | /// | |
852 | /// let uc = UnsafeCell::new(5); | |
853 | /// | |
d9579d0f | 854 | /// let five = uc.get(); |
85aaf69f | 855 | /// ``` |
1a4d82fc | 856 | #[inline] |
85aaf69f | 857 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 858 | pub fn get(&self) -> *mut T { |
d9579d0f AL |
859 | &self.value as *const T as *mut T |
860 | } | |
1a4d82fc | 861 | } |