]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | #![allow(deprecated)] |
2 | ||
041b39d2 XL |
3 | //! Single-threaded reference-counting pointers. 'Rc' stands for 'Reference |
4 | //! Counted'. | |
1a4d82fc | 5 | //! |
476ff2be | 6 | //! The type [`Rc<T>`][`Rc`] provides shared ownership of a value of type `T`, |
cc61c64b | 7 | //! allocated in the heap. Invoking [`clone`][clone] on [`Rc`] produces a new |
476ff2be | 8 | //! pointer to the same value in the heap. When the last [`Rc`] pointer to a |
c30ab7b3 | 9 | //! given value is destroyed, the pointed-to value is also destroyed. |
1a4d82fc | 10 | //! |
8bb4bdeb | 11 | //! Shared references in Rust disallow mutation by default, and [`Rc`] |
ea8adc8c | 12 | //! is no exception: you cannot generally obtain a mutable reference to |
8bb4bdeb XL |
13 | //! something inside an [`Rc`]. If you need mutability, put a [`Cell`] |
14 | //! or [`RefCell`] inside the [`Rc`]; see [an example of mutability | |
15 | //! inside an Rc][mutability]. | |
1a4d82fc | 16 | //! |
476ff2be SL |
17 | //! [`Rc`] uses non-atomic reference counting. This means that overhead is very |
18 | //! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`] | |
9e0c209e | 19 | //! does not implement [`Send`][send]. As a result, the Rust compiler |
476ff2be | 20 | //! will check *at compile time* that you are not sending [`Rc`]s between |
9e0c209e SL |
21 | //! threads. If you need multi-threaded, atomic reference counting, use |
22 | //! [`sync::Arc`][arc]. | |
23 | //! | |
cc61c64b | 24 | //! The [`downgrade`][downgrade] method can be used to create a non-owning |
476ff2be SL |
25 | //! [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d |
26 | //! to an [`Rc`], but this will return [`None`] if the value has | |
9e0c209e SL |
27 | //! already been dropped. |
28 | //! | |
476ff2be SL |
29 | //! A cycle between [`Rc`] pointers will never be deallocated. For this reason, |
30 | //! [`Weak`] is used to break cycles. For example, a tree could have strong | |
31 | //! [`Rc`] pointers from parent nodes to children, and [`Weak`] pointers from | |
9e0c209e SL |
32 | //! children back to their parents. |
33 | //! | |
476ff2be SL |
34 | //! `Rc<T>` automatically dereferences to `T` (via the [`Deref`] trait), |
35 | //! so you can call `T`'s methods on a value of type [`Rc<T>`][`Rc`]. To avoid name | |
13cf67c4 XL |
36 | //! clashes with `T`'s methods, the methods of [`Rc<T>`][`Rc`] itself are associated |
37 | //! functions, called using function-like syntax: | |
9e0c209e SL |
38 | //! |
39 | //! ``` | |
c30ab7b3 SL |
40 | //! use std::rc::Rc; |
41 | //! let my_rc = Rc::new(()); | |
42 | //! | |
9e0c209e SL |
43 | //! Rc::downgrade(&my_rc); |
44 | //! ``` | |
45 | //! | |
476ff2be | 46 | //! [`Weak<T>`][`Weak`] does not auto-dereference to `T`, because the value may have |
9e0c209e SL |
47 | //! already been destroyed. |
48 | //! | |
7cac9316 XL |
49 | //! # Cloning references |
50 | //! | |
51 | //! Creating a new reference from an existing reference counted pointer is done using the | |
52 | //! `Clone` trait implemented for [`Rc<T>`][`Rc`] and [`Weak<T>`][`Weak`]. | |
53 | //! | |
54 | //! ``` | |
55 | //! use std::rc::Rc; | |
56 | //! let foo = Rc::new(vec![1.0, 2.0, 3.0]); | |
57 | //! // The two syntaxes below are equivalent. | |
58 | //! let a = foo.clone(); | |
59 | //! let b = Rc::clone(&foo); | |
60 | //! // a and b both point to the same memory location as foo. | |
61 | //! ``` | |
62 | //! | |
63 | //! The `Rc::clone(&from)` syntax is the most idiomatic because it conveys more explicitly | |
64 | //! the meaning of the code. In the example above, this syntax makes it easier to see that | |
65 | //! this code is creating a new reference rather than copying the whole content of foo. | |
66 | //! | |
1a4d82fc JJ |
67 | //! # Examples |
68 | //! | |
69 | //! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`. | |
70 | //! We want to have our `Gadget`s point to their `Owner`. We can't do this with | |
71 | //! unique ownership, because more than one gadget may belong to the same | |
476ff2be | 72 | //! `Owner`. [`Rc`] allows us to share an `Owner` between multiple `Gadget`s, |
1a4d82fc JJ |
73 | //! and have the `Owner` remain allocated as long as any `Gadget` points at it. |
74 | //! | |
9e0c209e | 75 | //! ``` |
1a4d82fc JJ |
76 | //! use std::rc::Rc; |
77 | //! | |
78 | //! struct Owner { | |
9e0c209e | 79 | //! name: String, |
1a4d82fc JJ |
80 | //! // ...other fields |
81 | //! } | |
82 | //! | |
83 | //! struct Gadget { | |
85aaf69f | 84 | //! id: i32, |
9e0c209e | 85 | //! owner: Rc<Owner>, |
1a4d82fc JJ |
86 | //! // ...other fields |
87 | //! } | |
88 | //! | |
89 | //! fn main() { | |
9e0c209e SL |
90 | //! // Create a reference-counted `Owner`. |
91 | //! let gadget_owner: Rc<Owner> = Rc::new( | |
92 | //! Owner { | |
93 | //! name: "Gadget Man".to_string(), | |
94 | //! } | |
1a4d82fc JJ |
95 | //! ); |
96 | //! | |
9e0c209e SL |
97 | //! // Create `Gadget`s belonging to `gadget_owner`. Cloning the `Rc<Owner>` |
98 | //! // value gives us a new pointer to the same `Owner` value, incrementing | |
99 | //! // the reference count in the process. | |
100 | //! let gadget1 = Gadget { | |
101 | //! id: 1, | |
7cac9316 | 102 | //! owner: Rc::clone(&gadget_owner), |
9e0c209e SL |
103 | //! }; |
104 | //! let gadget2 = Gadget { | |
105 | //! id: 2, | |
7cac9316 | 106 | //! owner: Rc::clone(&gadget_owner), |
9e0c209e | 107 | //! }; |
1a4d82fc | 108 | //! |
9e0c209e | 109 | //! // Dispose of our local variable `gadget_owner`. |
1a4d82fc JJ |
110 | //! drop(gadget_owner); |
111 | //! | |
9e0c209e SL |
112 | //! // Despite dropping `gadget_owner`, we're still able to print out the name |
113 | //! // of the `Owner` of the `Gadget`s. This is because we've only dropped a | |
114 | //! // single `Rc<Owner>`, not the `Owner` it points to. As long as there are | |
115 | //! // other `Rc<Owner>` values pointing at the same `Owner`, it will remain | |
116 | //! // allocated. The field projection `gadget1.owner.name` works because | |
117 | //! // `Rc<Owner>` automatically dereferences to `Owner`. | |
1a4d82fc JJ |
118 | //! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name); |
119 | //! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name); | |
120 | //! | |
9e0c209e SL |
121 | //! // At the end of the function, `gadget1` and `gadget2` are destroyed, and |
122 | //! // with them the last counted references to our `Owner`. Gadget Man now | |
123 | //! // gets destroyed as well. | |
1a4d82fc JJ |
124 | //! } |
125 | //! ``` | |
126 | //! | |
c34b1796 | 127 | //! If our requirements change, and we also need to be able to traverse from |
476ff2be | 128 | //! `Owner` to `Gadget`, we will run into problems. An [`Rc`] pointer from `Owner` |
9e0c209e SL |
129 | //! to `Gadget` introduces a cycle between the values. This means that their |
130 | //! reference counts can never reach 0, and the values will remain allocated | |
476ff2be | 131 | //! forever: a memory leak. In order to get around this, we can use [`Weak`] |
9e0c209e | 132 | //! pointers. |
1a4d82fc | 133 | //! |
c34b1796 | 134 | //! Rust actually makes it somewhat difficult to produce this loop in the first |
9e0c209e | 135 | //! place. In order to end up with two values that point at each other, one of |
476ff2be | 136 | //! them needs to be mutable. This is difficult because [`Rc`] enforces |
9e0c209e | 137 | //! memory safety by only giving out shared references to the value it wraps, |
c34b1796 | 138 | //! and these don't allow direct mutation. We need to wrap the part of the |
476ff2be | 139 | //! value we wish to mutate in a [`RefCell`], which provides *interior |
c34b1796 | 140 | //! mutability*: a method to achieve mutability through a shared reference. |
476ff2be | 141 | //! [`RefCell`] enforces Rust's borrowing rules at runtime. |
1a4d82fc | 142 | //! |
9e0c209e | 143 | //! ``` |
1a4d82fc JJ |
144 | //! use std::rc::Rc; |
145 | //! use std::rc::Weak; | |
146 | //! use std::cell::RefCell; | |
147 | //! | |
148 | //! struct Owner { | |
149 | //! name: String, | |
e9174d1e | 150 | //! gadgets: RefCell<Vec<Weak<Gadget>>>, |
1a4d82fc JJ |
151 | //! // ...other fields |
152 | //! } | |
153 | //! | |
154 | //! struct Gadget { | |
85aaf69f | 155 | //! id: i32, |
e9174d1e | 156 | //! owner: Rc<Owner>, |
1a4d82fc JJ |
157 | //! // ...other fields |
158 | //! } | |
159 | //! | |
160 | //! fn main() { | |
9e0c209e SL |
161 | //! // Create a reference-counted `Owner`. Note that we've put the `Owner`'s |
162 | //! // vector of `Gadget`s inside a `RefCell` so that we can mutate it through | |
163 | //! // a shared reference. | |
164 | //! let gadget_owner: Rc<Owner> = Rc::new( | |
e9174d1e SL |
165 | //! Owner { |
166 | //! name: "Gadget Man".to_string(), | |
9e0c209e | 167 | //! gadgets: RefCell::new(vec![]), |
e9174d1e | 168 | //! } |
1a4d82fc JJ |
169 | //! ); |
170 | //! | |
9e0c209e SL |
171 | //! // Create `Gadget`s belonging to `gadget_owner`, as before. |
172 | //! let gadget1 = Rc::new( | |
173 | //! Gadget { | |
174 | //! id: 1, | |
7cac9316 | 175 | //! owner: Rc::clone(&gadget_owner), |
9e0c209e SL |
176 | //! } |
177 | //! ); | |
178 | //! let gadget2 = Rc::new( | |
179 | //! Gadget { | |
180 | //! id: 2, | |
7cac9316 | 181 | //! owner: Rc::clone(&gadget_owner), |
9e0c209e SL |
182 | //! } |
183 | //! ); | |
184 | //! | |
185 | //! // Add the `Gadget`s to their `Owner`. | |
186 | //! { | |
187 | //! let mut gadgets = gadget_owner.gadgets.borrow_mut(); | |
188 | //! gadgets.push(Rc::downgrade(&gadget1)); | |
189 | //! gadgets.push(Rc::downgrade(&gadget2)); | |
1a4d82fc | 190 | //! |
9e0c209e SL |
191 | //! // `RefCell` dynamic borrow ends here. |
192 | //! } | |
1a4d82fc | 193 | //! |
9e0c209e SL |
194 | //! // Iterate over our `Gadget`s, printing their details out. |
195 | //! for gadget_weak in gadget_owner.gadgets.borrow().iter() { | |
1a4d82fc | 196 | //! |
9e0c209e SL |
197 | //! // `gadget_weak` is a `Weak<Gadget>`. Since `Weak` pointers can't |
198 | //! // guarantee the value is still allocated, we need to call | |
199 | //! // `upgrade`, which returns an `Option<Rc<Gadget>>`. | |
200 | //! // | |
201 | //! // In this case we know the value still exists, so we simply | |
202 | //! // `unwrap` the `Option`. In a more complicated program, you might | |
203 | //! // need graceful error handling for a `None` result. | |
204 | //! | |
205 | //! let gadget = gadget_weak.upgrade().unwrap(); | |
1a4d82fc JJ |
206 | //! println!("Gadget {} owned by {}", gadget.id, gadget.owner.name); |
207 | //! } | |
208 | //! | |
9e0c209e SL |
209 | //! // At the end of the function, `gadget_owner`, `gadget1`, and `gadget2` |
210 | //! // are destroyed. There are now no strong (`Rc`) pointers to the | |
211 | //! // gadgets, so they are destroyed. This zeroes the reference count on | |
212 | //! // Gadget Man, so he gets destroyed as well. | |
1a4d82fc JJ |
213 | //! } |
214 | //! ``` | |
476ff2be SL |
215 | //! |
216 | //! [`Rc`]: struct.Rc.html | |
217 | //! [`Weak`]: struct.Weak.html | |
218 | //! [clone]: ../../std/clone/trait.Clone.html#tymethod.clone | |
219 | //! [`Cell`]: ../../std/cell/struct.Cell.html | |
220 | //! [`RefCell`]: ../../std/cell/struct.RefCell.html | |
221 | //! [send]: ../../std/marker/trait.Send.html | |
222 | //! [arc]: ../../std/sync/struct.Arc.html | |
223 | //! [`Deref`]: ../../std/ops/trait.Deref.html | |
224 | //! [downgrade]: struct.Rc.html#method.downgrade | |
225 | //! [upgrade]: struct.Weak.html#method.upgrade | |
226 | //! [`None`]: ../../std/option/enum.Option.html#variant.None | |
8bb4bdeb | 227 | //! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable |
1a4d82fc | 228 | |
85aaf69f | 229 | #![stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 230 | |
c34b1796 | 231 | #[cfg(not(test))] |
62682a34 | 232 | use boxed::Box; |
c34b1796 | 233 | #[cfg(test)] |
62682a34 SL |
234 | use std::boxed::Box; |
235 | ||
ea8adc8c | 236 | use core::any::Any; |
e9174d1e | 237 | use core::borrow; |
1a4d82fc | 238 | use core::cell::Cell; |
62682a34 | 239 | use core::cmp::Ordering; |
1a4d82fc | 240 | use core::fmt; |
3157f602 | 241 | use core::hash::{Hash, Hasher}; |
7cac9316 | 242 | use core::intrinsics::abort; |
92a42be0 | 243 | use core::marker; |
b7449926 | 244 | use core::marker::{Unpin, Unsize, PhantomData}; |
8faf50e0 | 245 | use core::mem::{self, align_of_val, forget, size_of_val}; |
0731742a | 246 | use core::ops::{Deref, Receiver}; |
a1dfa0c6 | 247 | use core::ops::{CoerceUnsized, DispatchFromDyn}; |
0bf4aa26 | 248 | use core::pin::Pin; |
2c00a5a8 | 249 | use core::ptr::{self, NonNull}; |
92a42be0 | 250 | use core::convert::From; |
8faf50e0 | 251 | use core::usize; |
d9579d0f | 252 | |
94b46f34 | 253 | use alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; |
3b2f2976 XL |
254 | use string::String; |
255 | use vec::Vec; | |
1a4d82fc | 256 | |
d9579d0f | 257 | struct RcBox<T: ?Sized> { |
85aaf69f | 258 | strong: Cell<usize>, |
d9579d0f AL |
259 | weak: Cell<usize>, |
260 | value: T, | |
1a4d82fc JJ |
261 | } |
262 | ||
041b39d2 XL |
263 | /// A single-threaded reference-counting pointer. 'Rc' stands for 'Reference |
264 | /// Counted'. | |
9e0c209e SL |
265 | /// |
266 | /// See the [module-level documentation](./index.html) for more details. | |
1a4d82fc | 267 | /// |
9e0c209e | 268 | /// The inherent methods of `Rc` are all associated functions, which means |
0731742a | 269 | /// that you have to call them as e.g., [`Rc::get_mut(&mut value)`][get_mut] instead of |
476ff2be | 270 | /// `value.get_mut()`. This avoids conflicts with methods of the inner |
9e0c209e | 271 | /// type `T`. |
476ff2be SL |
272 | /// |
273 | /// [get_mut]: #method.get_mut | |
a1dfa0c6 | 274 | #[cfg_attr(not(test), lang = "rc")] |
d9579d0f AL |
275 | #[stable(feature = "rust1", since = "1.0.0")] |
276 | pub struct Rc<T: ?Sized> { | |
2c00a5a8 | 277 | ptr: NonNull<RcBox<T>>, |
ff7c6d11 | 278 | phantom: PhantomData<T>, |
d9579d0f | 279 | } |
1a4d82fc | 280 | |
92a42be0 | 281 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 282 | impl<T: ?Sized> !marker::Send for Rc<T> {} |
92a42be0 | 283 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f AL |
284 | impl<T: ?Sized> !marker::Sync for Rc<T> {} |
285 | ||
92a42be0 SL |
286 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
287 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {} | |
d9579d0f | 288 | |
a1dfa0c6 XL |
289 | #[unstable(feature = "dispatch_from_dyn", issue = "0")] |
290 | impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T> {} | |
291 | ||
1a4d82fc JJ |
292 | impl<T> Rc<T> { |
293 | /// Constructs a new `Rc<T>`. | |
294 | /// | |
295 | /// # Examples | |
296 | /// | |
297 | /// ``` | |
298 | /// use std::rc::Rc; | |
299 | /// | |
85aaf69f | 300 | /// let five = Rc::new(5); |
1a4d82fc | 301 | /// ``` |
85aaf69f | 302 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 303 | pub fn new(value: T) -> Rc<T> { |
3b2f2976 XL |
304 | Rc { |
305 | // there is an implicit weak pointer owned by all the strong | |
306 | // pointers, which ensures that the weak destructor never frees | |
307 | // the allocation while the strong destructor is running, even | |
308 | // if the weak pointer is stored inside the strong one. | |
2c00a5a8 | 309 | ptr: Box::into_raw_non_null(box RcBox { |
3b2f2976 XL |
310 | strong: Cell::new(1), |
311 | weak: Cell::new(1), | |
312 | value, | |
2c00a5a8 | 313 | }), |
ff7c6d11 | 314 | phantom: PhantomData, |
1a4d82fc JJ |
315 | } |
316 | } | |
62682a34 | 317 | |
0731742a XL |
318 | /// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then |
319 | /// `value` will be pinned in memory and unable to be moved. | |
320 | #[stable(feature = "pin", since = "1.33.0")] | |
321 | pub fn pin(value: T) -> Pin<Rc<T>> { | |
0bf4aa26 XL |
322 | unsafe { Pin::new_unchecked(Rc::new(value)) } |
323 | } | |
324 | ||
9e0c209e | 325 | /// Returns the contained value, if the `Rc` has exactly one strong reference. |
62682a34 | 326 | /// |
c30ab7b3 SL |
327 | /// Otherwise, an [`Err`][result] is returned with the same `Rc` that was |
328 | /// passed in. | |
62682a34 | 329 | /// |
54a0048b SL |
330 | /// This will succeed even if there are outstanding weak references. |
331 | /// | |
c30ab7b3 SL |
332 | /// [result]: ../../std/result/enum.Result.html |
333 | /// | |
62682a34 SL |
334 | /// # Examples |
335 | /// | |
336 | /// ``` | |
62682a34 SL |
337 | /// use std::rc::Rc; |
338 | /// | |
339 | /// let x = Rc::new(3); | |
340 | /// assert_eq!(Rc::try_unwrap(x), Ok(3)); | |
341 | /// | |
342 | /// let x = Rc::new(4); | |
7cac9316 | 343 | /// let _y = Rc::clone(&x); |
9e0c209e | 344 | /// assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4); |
62682a34 SL |
345 | /// ``` |
346 | #[inline] | |
e9174d1e SL |
347 | #[stable(feature = "rc_unique", since = "1.4.0")] |
348 | pub fn try_unwrap(this: Self) -> Result<T, Self> { | |
476ff2be | 349 | if Rc::strong_count(&this) == 1 { |
62682a34 | 350 | unsafe { |
e9174d1e SL |
351 | let val = ptr::read(&*this); // copy the contained object |
352 | ||
ff7c6d11 | 353 | // Indicate to Weaks that they can't be promoted by decrementing |
e9174d1e SL |
354 | // the strong count, and then remove the implicit "strong weak" |
355 | // pointer while also handling drop logic by just crafting a | |
356 | // fake Weak. | |
357 | this.dec_strong(); | |
54a0048b | 358 | let _weak = Weak { ptr: this.ptr }; |
e9174d1e | 359 | forget(this); |
62682a34 SL |
360 | Ok(val) |
361 | } | |
362 | } else { | |
e9174d1e | 363 | Err(this) |
62682a34 SL |
364 | } |
365 | } | |
ea8adc8c | 366 | } |
e9174d1e | 367 | |
ea8adc8c | 368 | impl<T: ?Sized> Rc<T> { |
476ff2be SL |
369 | /// Consumes the `Rc`, returning the wrapped pointer. |
370 | /// | |
371 | /// To avoid a memory leak the pointer must be converted back to an `Rc` using | |
372 | /// [`Rc::from_raw`][from_raw]. | |
373 | /// | |
374 | /// [from_raw]: struct.Rc.html#method.from_raw | |
9e0c209e SL |
375 | /// |
376 | /// # Examples | |
377 | /// | |
378 | /// ``` | |
9e0c209e SL |
379 | /// use std::rc::Rc; |
380 | /// | |
476ff2be SL |
381 | /// let x = Rc::new(10); |
382 | /// let x_ptr = Rc::into_raw(x); | |
383 | /// assert_eq!(unsafe { *x_ptr }, 10); | |
384 | /// ``` | |
8bb4bdeb XL |
385 | #[stable(feature = "rc_raw", since = "1.17.0")] |
386 | pub fn into_raw(this: Self) -> *const T { | |
7cac9316 | 387 | let ptr: *const T = &*this; |
476ff2be SL |
388 | mem::forget(this); |
389 | ptr | |
390 | } | |
391 | ||
392 | /// Constructs an `Rc` from a raw pointer. | |
393 | /// | |
394 | /// The raw pointer must have been previously returned by a call to a | |
395 | /// [`Rc::into_raw`][into_raw]. | |
396 | /// | |
397 | /// This function is unsafe because improper use may lead to memory problems. For example, a | |
398 | /// double-free may occur if the function is called twice on the same raw pointer. | |
399 | /// | |
400 | /// [into_raw]: struct.Rc.html#method.into_raw | |
401 | /// | |
402 | /// # Examples | |
9e0c209e | 403 | /// |
9e0c209e | 404 | /// ``` |
476ff2be SL |
405 | /// use std::rc::Rc; |
406 | /// | |
407 | /// let x = Rc::new(10); | |
408 | /// let x_ptr = Rc::into_raw(x); | |
409 | /// | |
410 | /// unsafe { | |
411 | /// // Convert back to an `Rc` to prevent leak. | |
412 | /// let x = Rc::from_raw(x_ptr); | |
413 | /// assert_eq!(*x, 10); | |
414 | /// | |
415 | /// // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe. | |
416 | /// } | |
417 | /// | |
418 | /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! | |
419 | /// ``` | |
8bb4bdeb XL |
420 | #[stable(feature = "rc_raw", since = "1.17.0")] |
421 | pub unsafe fn from_raw(ptr: *const T) -> Self { | |
ea8adc8c XL |
422 | // Align the unsized value to the end of the RcBox. |
423 | // Because it is ?Sized, it will always be the last field in memory. | |
424 | let align = align_of_val(&*ptr); | |
425 | let layout = Layout::new::<RcBox<()>>(); | |
426 | let offset = (layout.size() + layout.padding_needed_for(align)) as isize; | |
427 | ||
428 | // Reverse the offset to find the original RcBox. | |
429 | let fake_ptr = ptr as *mut RcBox<T>; | |
430 | let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); | |
7cac9316 | 431 | |
7cac9316 | 432 | Rc { |
2c00a5a8 | 433 | ptr: NonNull::new_unchecked(rc_ptr), |
ff7c6d11 | 434 | phantom: PhantomData, |
cc61c64b XL |
435 | } |
436 | } | |
cc61c64b | 437 | |
9e0c209e SL |
438 | /// Creates a new [`Weak`][weak] pointer to this value. |
439 | /// | |
440 | /// [weak]: struct.Weak.html | |
d9579d0f AL |
441 | /// |
442 | /// # Examples | |
443 | /// | |
444 | /// ``` | |
d9579d0f AL |
445 | /// use std::rc::Rc; |
446 | /// | |
447 | /// let five = Rc::new(5); | |
448 | /// | |
e9174d1e | 449 | /// let weak_five = Rc::downgrade(&five); |
d9579d0f | 450 | /// ``` |
e9174d1e SL |
451 | #[stable(feature = "rc_weak", since = "1.4.0")] |
452 | pub fn downgrade(this: &Self) -> Weak<T> { | |
453 | this.inc_weak(); | |
8faf50e0 XL |
454 | // Make sure we do not create a dangling Weak |
455 | debug_assert!(!is_dangling(this.ptr)); | |
54a0048b | 456 | Weak { ptr: this.ptr } |
d9579d0f | 457 | } |
d9579d0f | 458 | |
9e0c209e SL |
459 | /// Gets the number of [`Weak`][weak] pointers to this value. |
460 | /// | |
461 | /// [weak]: struct.Weak.html | |
462 | /// | |
463 | /// # Examples | |
464 | /// | |
465 | /// ``` | |
9e0c209e SL |
466 | /// use std::rc::Rc; |
467 | /// | |
468 | /// let five = Rc::new(5); | |
469 | /// let _weak_five = Rc::downgrade(&five); | |
470 | /// | |
471 | /// assert_eq!(1, Rc::weak_count(&five)); | |
472 | /// ``` | |
62682a34 | 473 | #[inline] |
476ff2be | 474 | #[stable(feature = "rc_counts", since = "1.15.0")] |
b039eaaf SL |
475 | pub fn weak_count(this: &Self) -> usize { |
476 | this.weak() - 1 | |
477 | } | |
62682a34 | 478 | |
9e0c209e SL |
479 | /// Gets the number of strong (`Rc`) pointers to this value. |
480 | /// | |
481 | /// # Examples | |
482 | /// | |
483 | /// ``` | |
9e0c209e SL |
484 | /// use std::rc::Rc; |
485 | /// | |
486 | /// let five = Rc::new(5); | |
7cac9316 | 487 | /// let _also_five = Rc::clone(&five); |
9e0c209e SL |
488 | /// |
489 | /// assert_eq!(2, Rc::strong_count(&five)); | |
490 | /// ``` | |
62682a34 | 491 | #[inline] |
476ff2be | 492 | #[stable(feature = "rc_counts", since = "1.15.0")] |
b039eaaf SL |
493 | pub fn strong_count(this: &Self) -> usize { |
494 | this.strong() | |
495 | } | |
62682a34 | 496 | |
9e0c209e SL |
497 | /// Returns true if there are no other `Rc` or [`Weak`][weak] pointers to |
498 | /// this inner value. | |
499 | /// | |
500 | /// [weak]: struct.Weak.html | |
62682a34 | 501 | #[inline] |
cc61c64b | 502 | fn is_unique(this: &Self) -> bool { |
e9174d1e | 503 | Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1 |
62682a34 SL |
504 | } |
505 | ||
9e0c209e SL |
506 | /// Returns a mutable reference to the inner value, if there are |
507 | /// no other `Rc` or [`Weak`][weak] pointers to the same value. | |
62682a34 | 508 | /// |
476ff2be | 509 | /// Returns [`None`] otherwise, because it is not safe to |
9e0c209e SL |
510 | /// mutate a shared value. |
511 | /// | |
512 | /// See also [`make_mut`][make_mut], which will [`clone`][clone] | |
513 | /// the inner value when it's shared. | |
514 | /// | |
515 | /// [weak]: struct.Weak.html | |
476ff2be | 516 | /// [`None`]: ../../std/option/enum.Option.html#variant.None |
9e0c209e SL |
517 | /// [make_mut]: struct.Rc.html#method.make_mut |
518 | /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone | |
62682a34 SL |
519 | /// |
520 | /// # Examples | |
521 | /// | |
522 | /// ``` | |
62682a34 SL |
523 | /// use std::rc::Rc; |
524 | /// | |
525 | /// let mut x = Rc::new(3); | |
526 | /// *Rc::get_mut(&mut x).unwrap() = 4; | |
527 | /// assert_eq!(*x, 4); | |
528 | /// | |
7cac9316 | 529 | /// let _y = Rc::clone(&x); |
62682a34 SL |
530 | /// assert!(Rc::get_mut(&mut x).is_none()); |
531 | /// ``` | |
532 | #[inline] | |
e9174d1e SL |
533 | #[stable(feature = "rc_unique", since = "1.4.0")] |
534 | pub fn get_mut(this: &mut Self) -> Option<&mut T> { | |
535 | if Rc::is_unique(this) { | |
7cac9316 XL |
536 | unsafe { |
537 | Some(&mut this.ptr.as_mut().value) | |
538 | } | |
62682a34 SL |
539 | } else { |
540 | None | |
541 | } | |
1a4d82fc | 542 | } |
9e0c209e SL |
543 | |
544 | #[inline] | |
8bb4bdeb | 545 | #[stable(feature = "ptr_eq", since = "1.17.0")] |
9e0c209e SL |
546 | /// Returns true if the two `Rc`s point to the same value (not |
547 | /// just values that compare as equal). | |
548 | /// | |
549 | /// # Examples | |
550 | /// | |
551 | /// ``` | |
9e0c209e SL |
552 | /// use std::rc::Rc; |
553 | /// | |
554 | /// let five = Rc::new(5); | |
7cac9316 | 555 | /// let same_five = Rc::clone(&five); |
9e0c209e SL |
556 | /// let other_five = Rc::new(5); |
557 | /// | |
558 | /// assert!(Rc::ptr_eq(&five, &same_five)); | |
559 | /// assert!(!Rc::ptr_eq(&five, &other_five)); | |
560 | /// ``` | |
561 | pub fn ptr_eq(this: &Self, other: &Self) -> bool { | |
7cac9316 | 562 | this.ptr.as_ptr() == other.ptr.as_ptr() |
9e0c209e | 563 | } |
1a4d82fc JJ |
564 | } |
565 | ||
1a4d82fc | 566 | impl<T: Clone> Rc<T> { |
9e0c209e SL |
567 | /// Makes a mutable reference into the given `Rc`. |
568 | /// | |
569 | /// If there are other `Rc` or [`Weak`][weak] pointers to the same value, | |
570 | /// then `make_mut` will invoke [`clone`][clone] on the inner value to | |
571 | /// ensure unique ownership. This is also referred to as clone-on-write. | |
572 | /// | |
573 | /// See also [`get_mut`][get_mut], which will fail rather than cloning. | |
1a4d82fc | 574 | /// |
9e0c209e SL |
575 | /// [weak]: struct.Weak.html |
576 | /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone | |
577 | /// [get_mut]: struct.Rc.html#method.get_mut | |
1a4d82fc JJ |
578 | /// |
579 | /// # Examples | |
580 | /// | |
581 | /// ``` | |
582 | /// use std::rc::Rc; | |
583 | /// | |
e9174d1e SL |
584 | /// let mut data = Rc::new(5); |
585 | /// | |
9e0c209e | 586 | /// *Rc::make_mut(&mut data) += 1; // Won't clone anything |
7cac9316 | 587 | /// let mut other_data = Rc::clone(&data); // Won't clone inner data |
9e0c209e SL |
588 | /// *Rc::make_mut(&mut data) += 1; // Clones inner data |
589 | /// *Rc::make_mut(&mut data) += 1; // Won't clone anything | |
590 | /// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything | |
e9174d1e | 591 | /// |
9e0c209e | 592 | /// // Now `data` and `other_data` point to different values. |
e9174d1e SL |
593 | /// assert_eq!(*data, 8); |
594 | /// assert_eq!(*other_data, 12); | |
1a4d82fc JJ |
595 | /// ``` |
596 | #[inline] | |
e9174d1e SL |
597 | #[stable(feature = "rc_unique", since = "1.4.0")] |
598 | pub fn make_mut(this: &mut Self) -> &mut T { | |
599 | if Rc::strong_count(this) != 1 { | |
600 | // Gotta clone the data, there are other Rcs | |
601 | *this = Rc::new((**this).clone()) | |
602 | } else if Rc::weak_count(this) != 0 { | |
603 | // Can just steal the data, all that's left is Weaks | |
604 | unsafe { | |
7cac9316 | 605 | let mut swap = Rc::new(ptr::read(&this.ptr.as_ref().value)); |
e9174d1e SL |
606 | mem::swap(this, &mut swap); |
607 | swap.dec_strong(); | |
608 | // Remove implicit strong-weak ref (no need to craft a fake | |
609 | // Weak here -- we know other Weaks can clean up for us) | |
610 | swap.dec_weak(); | |
611 | forget(swap); | |
612 | } | |
1a4d82fc | 613 | } |
c34b1796 AL |
614 | // This unsafety is ok because we're guaranteed that the pointer |
615 | // returned is the *only* pointer that will ever be returned to T. Our | |
616 | // reference count is guaranteed to be 1 at this point, and we required | |
617 | // the `Rc<T>` itself to be `mut`, so we're returning the only possible | |
618 | // reference to the inner value. | |
7cac9316 XL |
619 | unsafe { |
620 | &mut this.ptr.as_mut().value | |
621 | } | |
1a4d82fc JJ |
622 | } |
623 | } | |
624 | ||
8faf50e0 | 625 | impl Rc<dyn Any> { |
ea8adc8c | 626 | #[inline] |
8faf50e0 | 627 | #[stable(feature = "rc_downcast", since = "1.29.0")] |
a1dfa0c6 | 628 | /// Attempt to downcast the `Rc<dyn Any>` to a concrete type. |
ea8adc8c XL |
629 | /// |
630 | /// # Examples | |
631 | /// | |
632 | /// ``` | |
ea8adc8c XL |
633 | /// use std::any::Any; |
634 | /// use std::rc::Rc; | |
635 | /// | |
a1dfa0c6 | 636 | /// fn print_if_string(value: Rc<dyn Any>) { |
ea8adc8c XL |
637 | /// if let Ok(string) = value.downcast::<String>() { |
638 | /// println!("String ({}): {}", string.len(), string); | |
639 | /// } | |
640 | /// } | |
641 | /// | |
642 | /// fn main() { | |
643 | /// let my_string = "Hello World".to_string(); | |
644 | /// print_if_string(Rc::new(my_string)); | |
645 | /// print_if_string(Rc::new(0i8)); | |
646 | /// } | |
647 | /// ``` | |
8faf50e0 | 648 | pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> { |
ea8adc8c | 649 | if (*self).is::<T>() { |
94b46f34 XL |
650 | let ptr = self.ptr.cast::<RcBox<T>>(); |
651 | forget(self); | |
652 | Ok(Rc { ptr, phantom: PhantomData }) | |
ea8adc8c XL |
653 | } else { |
654 | Err(self) | |
655 | } | |
656 | } | |
657 | } | |
658 | ||
3b2f2976 XL |
659 | impl<T: ?Sized> Rc<T> { |
660 | // Allocates an `RcBox<T>` with sufficient space for an unsized value | |
661 | unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> { | |
a1dfa0c6 XL |
662 | // Calculate layout using the given value. |
663 | // Previously, layout was calculated on the expression | |
664 | // `&*(ptr as *const RcBox<T>)`, but this created a misaligned | |
665 | // reference (see #54908). | |
666 | let layout = Layout::new::<RcBox<()>>() | |
667 | .extend(Layout::for_value(&*ptr)).unwrap().0 | |
668 | .pad_to_align().unwrap(); | |
3b2f2976 | 669 | |
83c7162d | 670 | let mem = Global.alloc(layout) |
94b46f34 | 671 | .unwrap_or_else(|_| handle_alloc_error(layout)); |
3b2f2976 | 672 | |
a1dfa0c6 | 673 | // Initialize the RcBox |
83c7162d | 674 | let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox<T>; |
a1dfa0c6 | 675 | debug_assert_eq!(Layout::for_value(&*inner), layout); |
3b2f2976 XL |
676 | |
677 | ptr::write(&mut (*inner).strong, Cell::new(1)); | |
678 | ptr::write(&mut (*inner).weak, Cell::new(1)); | |
679 | ||
680 | inner | |
681 | } | |
682 | ||
683 | fn from_box(v: Box<T>) -> Rc<T> { | |
684 | unsafe { | |
83c7162d XL |
685 | let box_unique = Box::into_unique(v); |
686 | let bptr = box_unique.as_ptr(); | |
3b2f2976 XL |
687 | |
688 | let value_size = size_of_val(&*bptr); | |
689 | let ptr = Self::allocate_for_ptr(bptr); | |
690 | ||
691 | // Copy value as bytes | |
692 | ptr::copy_nonoverlapping( | |
693 | bptr as *const T as *const u8, | |
694 | &mut (*ptr).value as *mut _ as *mut u8, | |
695 | value_size); | |
696 | ||
697 | // Free the allocation without dropping its contents | |
83c7162d | 698 | box_free(box_unique); |
3b2f2976 | 699 | |
2c00a5a8 | 700 | Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } |
3b2f2976 XL |
701 | } |
702 | } | |
703 | } | |
704 | ||
705 | // Sets the data pointer of a `?Sized` raw pointer. | |
706 | // | |
707 | // For a slice/trait object, this sets the `data` field and leaves the rest | |
708 | // unchanged. For a sized raw pointer, this simply sets the pointer. | |
709 | unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T { | |
710 | ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8); | |
711 | ptr | |
712 | } | |
713 | ||
714 | impl<T> Rc<[T]> { | |
715 | // Copy elements from slice into newly allocated Rc<[T]> | |
716 | // | |
717 | // Unsafe because the caller must either take ownership or bind `T: Copy` | |
718 | unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { | |
719 | let v_ptr = v as *const [T]; | |
720 | let ptr = Self::allocate_for_ptr(v_ptr); | |
721 | ||
722 | ptr::copy_nonoverlapping( | |
723 | v.as_ptr(), | |
724 | &mut (*ptr).value as *mut [T] as *mut T, | |
725 | v.len()); | |
726 | ||
2c00a5a8 | 727 | Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } |
3b2f2976 XL |
728 | } |
729 | } | |
730 | ||
731 | trait RcFromSlice<T> { | |
732 | fn from_slice(slice: &[T]) -> Self; | |
733 | } | |
734 | ||
735 | impl<T: Clone> RcFromSlice<T> for Rc<[T]> { | |
736 | #[inline] | |
737 | default fn from_slice(v: &[T]) -> Self { | |
738 | // Panic guard while cloning T elements. | |
739 | // In the event of a panic, elements that have been written | |
740 | // into the new RcBox will be dropped, then the memory freed. | |
741 | struct Guard<T> { | |
94b46f34 | 742 | mem: NonNull<u8>, |
3b2f2976 XL |
743 | elems: *mut T, |
744 | layout: Layout, | |
745 | n_elems: usize, | |
746 | } | |
747 | ||
748 | impl<T> Drop for Guard<T> { | |
749 | fn drop(&mut self) { | |
750 | use core::slice::from_raw_parts_mut; | |
751 | ||
752 | unsafe { | |
753 | let slice = from_raw_parts_mut(self.elems, self.n_elems); | |
754 | ptr::drop_in_place(slice); | |
755 | ||
83c7162d | 756 | Global.dealloc(self.mem, self.layout.clone()); |
3b2f2976 XL |
757 | } |
758 | } | |
759 | } | |
760 | ||
761 | unsafe { | |
762 | let v_ptr = v as *const [T]; | |
763 | let ptr = Self::allocate_for_ptr(v_ptr); | |
764 | ||
94b46f34 | 765 | let mem = ptr as *mut _ as *mut u8; |
3b2f2976 XL |
766 | let layout = Layout::for_value(&*ptr); |
767 | ||
768 | // Pointer to first element | |
769 | let elems = &mut (*ptr).value as *mut [T] as *mut T; | |
770 | ||
771 | let mut guard = Guard{ | |
83c7162d | 772 | mem: NonNull::new_unchecked(mem), |
3b2f2976 XL |
773 | elems: elems, |
774 | layout: layout, | |
775 | n_elems: 0, | |
776 | }; | |
777 | ||
778 | for (i, item) in v.iter().enumerate() { | |
b7449926 | 779 | ptr::write(elems.add(i), item.clone()); |
3b2f2976 XL |
780 | guard.n_elems += 1; |
781 | } | |
782 | ||
783 | // All clear. Forget the guard so it doesn't free the new RcBox. | |
784 | forget(guard); | |
785 | ||
2c00a5a8 | 786 | Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } |
3b2f2976 XL |
787 | } |
788 | } | |
789 | } | |
790 | ||
791 | impl<T: Copy> RcFromSlice<T> for Rc<[T]> { | |
792 | #[inline] | |
793 | fn from_slice(v: &[T]) -> Self { | |
794 | unsafe { Rc::copy_from_slice(v) } | |
795 | } | |
796 | } | |
797 | ||
d9579d0f AL |
798 | #[stable(feature = "rust1", since = "1.0.0")] |
799 | impl<T: ?Sized> Deref for Rc<T> { | |
800 | type Target = T; | |
801 | ||
802 | #[inline(always)] | |
803 | fn deref(&self) -> &T { | |
804 | &self.inner().value | |
805 | } | |
806 | } | |
1a4d82fc | 807 | |
0731742a XL |
808 | #[unstable(feature = "receiver_trait", issue = "0")] |
809 | impl<T: ?Sized> Receiver for Rc<T> {} | |
810 | ||
d9579d0f | 811 | #[stable(feature = "rust1", since = "1.0.0")] |
32a655c1 | 812 | unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc<T> { |
9e0c209e | 813 | /// Drops the `Rc`. |
d9579d0f AL |
814 | /// |
815 | /// This will decrement the strong reference count. If the strong reference | |
c30ab7b3 | 816 | /// count reaches zero then the only other references (if any) are |
b7449926 | 817 | /// [`Weak`], so we `drop` the inner value. |
d9579d0f AL |
818 | /// |
819 | /// # Examples | |
820 | /// | |
821 | /// ``` | |
d9579d0f AL |
822 | /// use std::rc::Rc; |
823 | /// | |
9e0c209e | 824 | /// struct Foo; |
d9579d0f | 825 | /// |
9e0c209e SL |
826 | /// impl Drop for Foo { |
827 | /// fn drop(&mut self) { | |
828 | /// println!("dropped!"); | |
829 | /// } | |
d9579d0f | 830 | /// } |
d9579d0f | 831 | /// |
9e0c209e | 832 | /// let foo = Rc::new(Foo); |
7cac9316 | 833 | /// let foo2 = Rc::clone(&foo); |
d9579d0f | 834 | /// |
9e0c209e SL |
835 | /// drop(foo); // Doesn't print anything |
836 | /// drop(foo2); // Prints "dropped!" | |
d9579d0f | 837 | /// ``` |
0731742a XL |
838 | /// |
839 | /// [`Weak`]: ../../std/rc/struct.Weak.html | |
d9579d0f AL |
840 | fn drop(&mut self) { |
841 | unsafe { | |
9e0c209e SL |
842 | self.dec_strong(); |
843 | if self.strong() == 0 { | |
844 | // destroy the contained object | |
7cac9316 | 845 | ptr::drop_in_place(self.ptr.as_mut()); |
d9579d0f | 846 | |
9e0c209e SL |
847 | // remove the implicit "strong weak" pointer now that we've |
848 | // destroyed the contents. | |
849 | self.dec_weak(); | |
d9579d0f | 850 | |
9e0c209e | 851 | if self.weak() == 0 { |
94b46f34 | 852 | Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())); |
d9579d0f AL |
853 | } |
854 | } | |
855 | } | |
856 | } | |
857 | } | |
858 | ||
d9579d0f AL |
859 | #[stable(feature = "rust1", since = "1.0.0")] |
860 | impl<T: ?Sized> Clone for Rc<T> { | |
9e0c209e | 861 | /// Makes a clone of the `Rc` pointer. |
d9579d0f | 862 | /// |
9e0c209e SL |
863 | /// This creates another pointer to the same inner value, increasing the |
864 | /// strong reference count. | |
d9579d0f AL |
865 | /// |
866 | /// # Examples | |
867 | /// | |
868 | /// ``` | |
d9579d0f AL |
869 | /// use std::rc::Rc; |
870 | /// | |
871 | /// let five = Rc::new(5); | |
872 | /// | |
0bf4aa26 | 873 | /// let _ = Rc::clone(&five); |
d9579d0f AL |
874 | /// ``` |
875 | #[inline] | |
876 | fn clone(&self) -> Rc<T> { | |
877 | self.inc_strong(); | |
ff7c6d11 | 878 | Rc { ptr: self.ptr, phantom: PhantomData } |
d9579d0f AL |
879 | } |
880 | } | |
1a4d82fc | 881 | |
85aaf69f | 882 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
883 | impl<T: Default> Default for Rc<T> { |
884 | /// Creates a new `Rc<T>`, with the `Default` value for `T`. | |
885 | /// | |
886 | /// # Examples | |
887 | /// | |
888 | /// ``` | |
889 | /// use std::rc::Rc; | |
1a4d82fc | 890 | /// |
85aaf69f | 891 | /// let x: Rc<i32> = Default::default(); |
9e0c209e | 892 | /// assert_eq!(*x, 0); |
1a4d82fc JJ |
893 | /// ``` |
894 | #[inline] | |
1a4d82fc JJ |
895 | fn default() -> Rc<T> { |
896 | Rc::new(Default::default()) | |
897 | } | |
898 | } | |
899 | ||
0731742a XL |
900 | #[stable(feature = "rust1", since = "1.0.0")] |
901 | trait RcEqIdent<T: ?Sized + PartialEq> { | |
902 | fn eq(&self, other: &Rc<T>) -> bool; | |
903 | fn ne(&self, other: &Rc<T>) -> bool; | |
904 | } | |
905 | ||
906 | #[stable(feature = "rust1", since = "1.0.0")] | |
907 | impl<T: ?Sized + PartialEq> RcEqIdent<T> for Rc<T> { | |
908 | #[inline] | |
909 | default fn eq(&self, other: &Rc<T>) -> bool { | |
910 | **self == **other | |
911 | } | |
912 | ||
913 | #[inline] | |
914 | default fn ne(&self, other: &Rc<T>) -> bool { | |
915 | **self != **other | |
916 | } | |
917 | } | |
918 | ||
919 | #[stable(feature = "rust1", since = "1.0.0")] | |
920 | impl<T: ?Sized + Eq> RcEqIdent<T> for Rc<T> { | |
921 | #[inline] | |
922 | fn eq(&self, other: &Rc<T>) -> bool { | |
923 | Rc::ptr_eq(self, other) || **self == **other | |
924 | } | |
925 | ||
926 | #[inline] | |
927 | fn ne(&self, other: &Rc<T>) -> bool { | |
928 | !Rc::ptr_eq(self, other) && **self != **other | |
929 | } | |
930 | } | |
931 | ||
85aaf69f | 932 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 933 | impl<T: ?Sized + PartialEq> PartialEq for Rc<T> { |
9e0c209e | 934 | /// Equality for two `Rc`s. |
1a4d82fc | 935 | /// |
9e0c209e | 936 | /// Two `Rc`s are equal if their inner values are equal. |
1a4d82fc | 937 | /// |
0731742a XL |
938 | /// If `T` also implements `Eq`, two `Rc`s that point to the same value are |
939 | /// always equal. | |
940 | /// | |
1a4d82fc JJ |
941 | /// # Examples |
942 | /// | |
943 | /// ``` | |
944 | /// use std::rc::Rc; | |
945 | /// | |
85aaf69f | 946 | /// let five = Rc::new(5); |
1a4d82fc | 947 | /// |
9e0c209e | 948 | /// assert!(five == Rc::new(5)); |
1a4d82fc | 949 | /// ``` |
0731742a | 950 | #[inline] |
b039eaaf | 951 | fn eq(&self, other: &Rc<T>) -> bool { |
0731742a | 952 | RcEqIdent::eq(self, other) |
b039eaaf | 953 | } |
1a4d82fc | 954 | |
9e0c209e | 955 | /// Inequality for two `Rc`s. |
1a4d82fc | 956 | /// |
9e0c209e | 957 | /// Two `Rc`s are unequal if their inner values are unequal. |
1a4d82fc | 958 | /// |
0731742a XL |
959 | /// If `T` also implements `Eq`, two `Rc`s that point to the same value are |
960 | /// never unequal. | |
961 | /// | |
1a4d82fc JJ |
962 | /// # Examples |
963 | /// | |
964 | /// ``` | |
965 | /// use std::rc::Rc; | |
966 | /// | |
85aaf69f | 967 | /// let five = Rc::new(5); |
1a4d82fc | 968 | /// |
9e0c209e | 969 | /// assert!(five != Rc::new(6)); |
1a4d82fc | 970 | /// ``` |
0731742a | 971 | #[inline] |
b039eaaf | 972 | fn ne(&self, other: &Rc<T>) -> bool { |
0731742a | 973 | RcEqIdent::ne(self, other) |
b039eaaf | 974 | } |
1a4d82fc JJ |
975 | } |
976 | ||
85aaf69f | 977 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 978 | impl<T: ?Sized + Eq> Eq for Rc<T> {} |
1a4d82fc | 979 | |
85aaf69f | 980 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 981 | impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { |
9e0c209e | 982 | /// Partial comparison for two `Rc`s. |
1a4d82fc JJ |
983 | /// |
984 | /// The two are compared by calling `partial_cmp()` on their inner values. | |
985 | /// | |
986 | /// # Examples | |
987 | /// | |
988 | /// ``` | |
989 | /// use std::rc::Rc; | |
9e0c209e | 990 | /// use std::cmp::Ordering; |
1a4d82fc | 991 | /// |
85aaf69f | 992 | /// let five = Rc::new(5); |
1a4d82fc | 993 | /// |
9e0c209e | 994 | /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Rc::new(6))); |
1a4d82fc JJ |
995 | /// ``` |
996 | #[inline(always)] | |
997 | fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> { | |
998 | (**self).partial_cmp(&**other) | |
999 | } | |
1000 | ||
9e0c209e | 1001 | /// Less-than comparison for two `Rc`s. |
1a4d82fc JJ |
1002 | /// |
1003 | /// The two are compared by calling `<` on their inner values. | |
1004 | /// | |
1005 | /// # Examples | |
1006 | /// | |
1007 | /// ``` | |
1008 | /// use std::rc::Rc; | |
1009 | /// | |
85aaf69f | 1010 | /// let five = Rc::new(5); |
1a4d82fc | 1011 | /// |
9e0c209e | 1012 | /// assert!(five < Rc::new(6)); |
1a4d82fc JJ |
1013 | /// ``` |
1014 | #[inline(always)] | |
b039eaaf SL |
1015 | fn lt(&self, other: &Rc<T>) -> bool { |
1016 | **self < **other | |
1017 | } | |
1a4d82fc | 1018 | |
9e0c209e | 1019 | /// 'Less than or equal to' comparison for two `Rc`s. |
1a4d82fc JJ |
1020 | /// |
1021 | /// The two are compared by calling `<=` on their inner values. | |
1022 | /// | |
1023 | /// # Examples | |
1024 | /// | |
1025 | /// ``` | |
1026 | /// use std::rc::Rc; | |
1027 | /// | |
85aaf69f | 1028 | /// let five = Rc::new(5); |
1a4d82fc | 1029 | /// |
9e0c209e | 1030 | /// assert!(five <= Rc::new(5)); |
1a4d82fc JJ |
1031 | /// ``` |
1032 | #[inline(always)] | |
b039eaaf SL |
1033 | fn le(&self, other: &Rc<T>) -> bool { |
1034 | **self <= **other | |
1035 | } | |
1a4d82fc | 1036 | |
9e0c209e | 1037 | /// Greater-than comparison for two `Rc`s. |
1a4d82fc JJ |
1038 | /// |
1039 | /// The two are compared by calling `>` on their inner values. | |
1040 | /// | |
1041 | /// # Examples | |
1042 | /// | |
1043 | /// ``` | |
1044 | /// use std::rc::Rc; | |
1045 | /// | |
85aaf69f | 1046 | /// let five = Rc::new(5); |
1a4d82fc | 1047 | /// |
9e0c209e | 1048 | /// assert!(five > Rc::new(4)); |
1a4d82fc JJ |
1049 | /// ``` |
1050 | #[inline(always)] | |
b039eaaf SL |
1051 | fn gt(&self, other: &Rc<T>) -> bool { |
1052 | **self > **other | |
1053 | } | |
1a4d82fc | 1054 | |
9e0c209e | 1055 | /// 'Greater than or equal to' comparison for two `Rc`s. |
1a4d82fc JJ |
1056 | /// |
1057 | /// The two are compared by calling `>=` on their inner values. | |
1058 | /// | |
1059 | /// # Examples | |
1060 | /// | |
1061 | /// ``` | |
1062 | /// use std::rc::Rc; | |
1063 | /// | |
85aaf69f | 1064 | /// let five = Rc::new(5); |
1a4d82fc | 1065 | /// |
9e0c209e | 1066 | /// assert!(five >= Rc::new(5)); |
1a4d82fc JJ |
1067 | /// ``` |
1068 | #[inline(always)] | |
b039eaaf SL |
1069 | fn ge(&self, other: &Rc<T>) -> bool { |
1070 | **self >= **other | |
1071 | } | |
1a4d82fc JJ |
1072 | } |
1073 | ||
85aaf69f | 1074 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 1075 | impl<T: ?Sized + Ord> Ord for Rc<T> { |
9e0c209e | 1076 | /// Comparison for two `Rc`s. |
1a4d82fc JJ |
1077 | /// |
1078 | /// The two are compared by calling `cmp()` on their inner values. | |
1079 | /// | |
1080 | /// # Examples | |
1081 | /// | |
1082 | /// ``` | |
1083 | /// use std::rc::Rc; | |
9e0c209e | 1084 | /// use std::cmp::Ordering; |
1a4d82fc | 1085 | /// |
85aaf69f | 1086 | /// let five = Rc::new(5); |
1a4d82fc | 1087 | /// |
9e0c209e | 1088 | /// assert_eq!(Ordering::Less, five.cmp(&Rc::new(6))); |
1a4d82fc JJ |
1089 | /// ``` |
1090 | #[inline] | |
b039eaaf SL |
1091 | fn cmp(&self, other: &Rc<T>) -> Ordering { |
1092 | (**self).cmp(&**other) | |
1093 | } | |
1a4d82fc JJ |
1094 | } |
1095 | ||
d9579d0f | 1096 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 1097 | impl<T: ?Sized + Hash> Hash for Rc<T> { |
d9579d0f AL |
1098 | fn hash<H: Hasher>(&self, state: &mut H) { |
1099 | (**self).hash(state); | |
1100 | } | |
1101 | } | |
1a4d82fc | 1102 | |
d9579d0f | 1103 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 1104 | impl<T: ?Sized + fmt::Display> fmt::Display for Rc<T> { |
d9579d0f AL |
1105 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1106 | fmt::Display::fmt(&**self, f) | |
1107 | } | |
1108 | } | |
1a4d82fc | 1109 | |
d9579d0f | 1110 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 1111 | impl<T: ?Sized + fmt::Debug> fmt::Debug for Rc<T> { |
d9579d0f AL |
1112 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1113 | fmt::Debug::fmt(&**self, f) | |
1114 | } | |
1115 | } | |
1a4d82fc | 1116 | |
9346a6ac | 1117 | #[stable(feature = "rust1", since = "1.0.0")] |
7453a54e | 1118 | impl<T: ?Sized> fmt::Pointer for Rc<T> { |
9346a6ac | 1119 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
ff7c6d11 | 1120 | fmt::Pointer::fmt(&(&**self as *const T), f) |
9346a6ac AL |
1121 | } |
1122 | } | |
1123 | ||
92a42be0 SL |
1124 | #[stable(feature = "from_for_ptrs", since = "1.6.0")] |
1125 | impl<T> From<T> for Rc<T> { | |
1126 | fn from(t: T) -> Self { | |
1127 | Rc::new(t) | |
1128 | } | |
1129 | } | |
1130 | ||
3b2f2976 XL |
1131 | #[stable(feature = "shared_from_slice", since = "1.21.0")] |
1132 | impl<'a, T: Clone> From<&'a [T]> for Rc<[T]> { | |
1133 | #[inline] | |
1134 | fn from(v: &[T]) -> Rc<[T]> { | |
1135 | <Self as RcFromSlice<T>>::from_slice(v) | |
1136 | } | |
1137 | } | |
1138 | ||
1139 | #[stable(feature = "shared_from_slice", since = "1.21.0")] | |
1140 | impl<'a> From<&'a str> for Rc<str> { | |
1141 | #[inline] | |
1142 | fn from(v: &str) -> Rc<str> { | |
ff7c6d11 XL |
1143 | let rc = Rc::<[u8]>::from(v.as_bytes()); |
1144 | unsafe { Rc::from_raw(Rc::into_raw(rc) as *const str) } | |
3b2f2976 XL |
1145 | } |
1146 | } | |
1147 | ||
1148 | #[stable(feature = "shared_from_slice", since = "1.21.0")] | |
1149 | impl From<String> for Rc<str> { | |
1150 | #[inline] | |
1151 | fn from(v: String) -> Rc<str> { | |
1152 | Rc::from(&v[..]) | |
1153 | } | |
1154 | } | |
1155 | ||
1156 | #[stable(feature = "shared_from_slice", since = "1.21.0")] | |
1157 | impl<T: ?Sized> From<Box<T>> for Rc<T> { | |
1158 | #[inline] | |
1159 | fn from(v: Box<T>) -> Rc<T> { | |
1160 | Rc::from_box(v) | |
1161 | } | |
1162 | } | |
1163 | ||
1164 | #[stable(feature = "shared_from_slice", since = "1.21.0")] | |
1165 | impl<T> From<Vec<T>> for Rc<[T]> { | |
1166 | #[inline] | |
1167 | fn from(mut v: Vec<T>) -> Rc<[T]> { | |
1168 | unsafe { | |
1169 | let rc = Rc::copy_from_slice(&v); | |
1170 | ||
1171 | // Allow the Vec to free its memory, but not destroy its contents | |
1172 | v.set_len(0); | |
1173 | ||
1174 | rc | |
1175 | } | |
1176 | } | |
1177 | } | |
1178 | ||
cc61c64b XL |
1179 | /// `Weak` is a version of [`Rc`] that holds a non-owning reference to the |
1180 | /// managed value. The value is accessed by calling [`upgrade`] on the `Weak` | |
1181 | /// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`. | |
9e0c209e | 1182 | /// |
cc61c64b XL |
1183 | /// Since a `Weak` reference does not count towards ownership, it will not |
1184 | /// prevent the inner value from being dropped, and `Weak` itself makes no | |
1185 | /// guarantees about the value still being present and may return [`None`] | |
1186 | /// when [`upgrade`]d. | |
9e0c209e | 1187 | /// |
cc61c64b XL |
1188 | /// A `Weak` pointer is useful for keeping a temporary reference to the value |
1189 | /// within [`Rc`] without extending its lifetime. It is also used to prevent | |
1190 | /// circular references between [`Rc`] pointers, since mutual owning references | |
3b2f2976 | 1191 | /// would never allow either [`Rc`] to be dropped. For example, a tree could |
cc61c64b XL |
1192 | /// have strong [`Rc`] pointers from parent nodes to children, and `Weak` |
1193 | /// pointers from children back to their parents. | |
1a4d82fc | 1194 | /// |
cc61c64b | 1195 | /// The typical way to obtain a `Weak` pointer is to call [`Rc::downgrade`]. |
1a4d82fc | 1196 | /// |
cc61c64b XL |
1197 | /// [`Rc`]: struct.Rc.html |
1198 | /// [`Rc::downgrade`]: struct.Rc.html#method.downgrade | |
1199 | /// [`upgrade`]: struct.Weak.html#method.upgrade | |
1200 | /// [`Option`]: ../../std/option/enum.Option.html | |
1201 | /// [`None`]: ../../std/option/enum.Option.html#variant.None | |
e9174d1e | 1202 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f | 1203 | pub struct Weak<T: ?Sized> { |
8faf50e0 XL |
1204 | // This is a `NonNull` to allow optimizing the size of this type in enums, |
1205 | // but it is not necessarily a valid pointer. | |
1206 | // `Weak::new` sets this to `usize::MAX` so that it doesn’t need | |
1207 | // to allocate space on the heap. That's not a value a real pointer | |
1208 | // will ever have because RcBox has alignment at least 2. | |
2c00a5a8 | 1209 | ptr: NonNull<RcBox<T>>, |
d9579d0f | 1210 | } |
1a4d82fc | 1211 | |
7453a54e | 1212 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f | 1213 | impl<T: ?Sized> !marker::Send for Weak<T> {} |
7453a54e | 1214 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f | 1215 | impl<T: ?Sized> !marker::Sync for Weak<T> {} |
85aaf69f | 1216 | |
92a42be0 SL |
1217 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
1218 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {} | |
c1a9b12d | 1219 | |
a1dfa0c6 XL |
1220 | #[unstable(feature = "dispatch_from_dyn", issue = "0")] |
1221 | impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {} | |
1222 | ||
a7813a04 | 1223 | impl<T> Weak<T> { |
8faf50e0 | 1224 | /// Constructs a new `Weak<T>`, without allocating any memory. |
0731742a | 1225 | /// Calling [`upgrade`] on the return value always gives [`None`]. |
a7813a04 | 1226 | /// |
0731742a | 1227 | /// [`upgrade`]: #method.upgrade |
cc61c64b | 1228 | /// [`None`]: ../../std/option/enum.Option.html |
a7813a04 XL |
1229 | /// |
1230 | /// # Examples | |
1231 | /// | |
1232 | /// ``` | |
1233 | /// use std::rc::Weak; | |
1234 | /// | |
1235 | /// let empty: Weak<i64> = Weak::new(); | |
9e0c209e | 1236 | /// assert!(empty.upgrade().is_none()); |
a7813a04 XL |
1237 | /// ``` |
1238 | #[stable(feature = "downgraded_weak", since = "1.10.0")] | |
1239 | pub fn new() -> Weak<T> { | |
8faf50e0 XL |
1240 | Weak { |
1241 | ptr: NonNull::new(usize::MAX as *mut RcBox<T>).expect("MAX is not 0"), | |
a7813a04 XL |
1242 | } |
1243 | } | |
1244 | } | |
1245 | ||
8faf50e0 XL |
1246 | pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool { |
1247 | let address = ptr.as_ptr() as *mut () as usize; | |
1248 | address == usize::MAX | |
1249 | } | |
1250 | ||
d9579d0f | 1251 | impl<T: ?Sized> Weak<T> { |
cc61c64b XL |
1252 | /// Attempts to upgrade the `Weak` pointer to an [`Rc`], extending |
1253 | /// the lifetime of the value if successful. | |
d9579d0f | 1254 | /// |
cc61c64b | 1255 | /// Returns [`None`] if the value has since been dropped. |
d9579d0f | 1256 | /// |
cc61c64b XL |
1257 | /// [`Rc`]: struct.Rc.html |
1258 | /// [`None`]: ../../std/option/enum.Option.html | |
d9579d0f AL |
1259 | /// |
1260 | /// # Examples | |
1261 | /// | |
1262 | /// ``` | |
d9579d0f AL |
1263 | /// use std::rc::Rc; |
1264 | /// | |
1265 | /// let five = Rc::new(5); | |
1266 | /// | |
e9174d1e | 1267 | /// let weak_five = Rc::downgrade(&five); |
d9579d0f AL |
1268 | /// |
1269 | /// let strong_five: Option<Rc<_>> = weak_five.upgrade(); | |
9e0c209e SL |
1270 | /// assert!(strong_five.is_some()); |
1271 | /// | |
1272 | /// // Destroy all strong pointers. | |
1273 | /// drop(strong_five); | |
1274 | /// drop(five); | |
1275 | /// | |
1276 | /// assert!(weak_five.upgrade().is_none()); | |
d9579d0f | 1277 | /// ``` |
e9174d1e | 1278 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f | 1279 | pub fn upgrade(&self) -> Option<Rc<T>> { |
8faf50e0 XL |
1280 | let inner = self.inner()?; |
1281 | if inner.strong() == 0 { | |
d9579d0f AL |
1282 | None |
1283 | } else { | |
8faf50e0 | 1284 | inner.inc_strong(); |
ff7c6d11 | 1285 | Some(Rc { ptr: self.ptr, phantom: PhantomData }) |
d9579d0f AL |
1286 | } |
1287 | } | |
8faf50e0 XL |
1288 | |
1289 | /// Return `None` when the pointer is dangling and there is no allocated `RcBox`, | |
0731742a | 1290 | /// i.e., this `Weak` was created by `Weak::new` |
8faf50e0 XL |
1291 | #[inline] |
1292 | fn inner(&self) -> Option<&RcBox<T>> { | |
1293 | if is_dangling(self.ptr) { | |
1294 | None | |
1295 | } else { | |
1296 | Some(unsafe { self.ptr.as_ref() }) | |
1297 | } | |
1298 | } | |
0731742a XL |
1299 | |
1300 | /// Returns true if the two `Weak`s point to the same value (not just values | |
1301 | /// that compare as equal). | |
1302 | /// | |
1303 | /// # Notes | |
1304 | /// | |
1305 | /// Since this compares pointers it means that `Weak::new()` will equal each | |
1306 | /// other, even though they don't point to any value. | |
1307 | /// | |
1308 | /// # Examples | |
1309 | /// | |
1310 | /// ``` | |
1311 | /// #![feature(weak_ptr_eq)] | |
1312 | /// use std::rc::{Rc, Weak}; | |
1313 | /// | |
1314 | /// let first_rc = Rc::new(5); | |
1315 | /// let first = Rc::downgrade(&first_rc); | |
1316 | /// let second = Rc::downgrade(&first_rc); | |
1317 | /// | |
1318 | /// assert!(Weak::ptr_eq(&first, &second)); | |
1319 | /// | |
1320 | /// let third_rc = Rc::new(5); | |
1321 | /// let third = Rc::downgrade(&third_rc); | |
1322 | /// | |
1323 | /// assert!(!Weak::ptr_eq(&first, &third)); | |
1324 | /// ``` | |
1325 | /// | |
1326 | /// Comparing `Weak::new`. | |
1327 | /// | |
1328 | /// ``` | |
1329 | /// #![feature(weak_ptr_eq)] | |
1330 | /// use std::rc::{Rc, Weak}; | |
1331 | /// | |
1332 | /// let first = Weak::new(); | |
1333 | /// let second = Weak::new(); | |
1334 | /// assert!(Weak::ptr_eq(&first, &second)); | |
1335 | /// | |
1336 | /// let third_rc = Rc::new(()); | |
1337 | /// let third = Rc::downgrade(&third_rc); | |
1338 | /// assert!(!Weak::ptr_eq(&first, &third)); | |
1339 | /// ``` | |
1340 | #[inline] | |
1341 | #[unstable(feature = "weak_ptr_eq", issue = "55981")] | |
1342 | pub fn ptr_eq(this: &Self, other: &Self) -> bool { | |
1343 | this.ptr.as_ptr() == other.ptr.as_ptr() | |
1344 | } | |
d9579d0f AL |
1345 | } |
1346 | ||
7453a54e | 1347 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f | 1348 | impl<T: ?Sized> Drop for Weak<T> { |
9e0c209e | 1349 | /// Drops the `Weak` pointer. |
d9579d0f | 1350 | /// |
d9579d0f AL |
1351 | /// # Examples |
1352 | /// | |
1353 | /// ``` | |
7cac9316 | 1354 | /// use std::rc::{Rc, Weak}; |
d9579d0f | 1355 | /// |
9e0c209e | 1356 | /// struct Foo; |
d9579d0f | 1357 | /// |
9e0c209e SL |
1358 | /// impl Drop for Foo { |
1359 | /// fn drop(&mut self) { | |
1360 | /// println!("dropped!"); | |
1361 | /// } | |
d9579d0f | 1362 | /// } |
d9579d0f | 1363 | /// |
9e0c209e SL |
1364 | /// let foo = Rc::new(Foo); |
1365 | /// let weak_foo = Rc::downgrade(&foo); | |
7cac9316 | 1366 | /// let other_weak_foo = Weak::clone(&weak_foo); |
9e0c209e SL |
1367 | /// |
1368 | /// drop(weak_foo); // Doesn't print anything | |
1369 | /// drop(foo); // Prints "dropped!" | |
d9579d0f | 1370 | /// |
9e0c209e | 1371 | /// assert!(other_weak_foo.upgrade().is_none()); |
d9579d0f AL |
1372 | /// ``` |
1373 | fn drop(&mut self) { | |
8faf50e0 XL |
1374 | if let Some(inner) = self.inner() { |
1375 | inner.dec_weak(); | |
9e0c209e SL |
1376 | // the weak count starts at 1, and will only go to zero if all |
1377 | // the strong pointers have disappeared. | |
8faf50e0 XL |
1378 | if inner.weak() == 0 { |
1379 | unsafe { | |
1380 | Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())); | |
1381 | } | |
d9579d0f AL |
1382 | } |
1383 | } | |
1384 | } | |
1385 | } | |
1386 | ||
e9174d1e | 1387 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f | 1388 | impl<T: ?Sized> Clone for Weak<T> { |
cc61c64b | 1389 | /// Makes a clone of the `Weak` pointer that points to the same value. |
d9579d0f AL |
1390 | /// |
1391 | /// # Examples | |
1392 | /// | |
1393 | /// ``` | |
7cac9316 | 1394 | /// use std::rc::{Rc, Weak}; |
d9579d0f | 1395 | /// |
e9174d1e | 1396 | /// let weak_five = Rc::downgrade(&Rc::new(5)); |
d9579d0f | 1397 | /// |
0bf4aa26 | 1398 | /// let _ = Weak::clone(&weak_five); |
d9579d0f AL |
1399 | /// ``` |
1400 | #[inline] | |
1401 | fn clone(&self) -> Weak<T> { | |
8faf50e0 XL |
1402 | if let Some(inner) = self.inner() { |
1403 | inner.inc_weak() | |
1404 | } | |
54a0048b | 1405 | Weak { ptr: self.ptr } |
d9579d0f AL |
1406 | } |
1407 | } | |
1a4d82fc | 1408 | |
7453a54e | 1409 | #[stable(feature = "rc_weak", since = "1.4.0")] |
92a42be0 | 1410 | impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> { |
d9579d0f AL |
1411 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1412 | write!(f, "(Weak)") | |
1413 | } | |
1414 | } | |
1a4d82fc | 1415 | |
a7813a04 XL |
1416 | #[stable(feature = "downgraded_weak", since = "1.10.0")] |
1417 | impl<T> Default for Weak<T> { | |
cc61c64b | 1418 | /// Constructs a new `Weak<T>`, allocating memory for `T` without initializing |
0731742a | 1419 | /// it. Calling [`upgrade`] on the return value always gives [`None`]. |
9e0c209e | 1420 | /// |
cc61c64b | 1421 | /// [`None`]: ../../std/option/enum.Option.html |
0731742a | 1422 | /// [`upgrade`]: ../../std/rc/struct.Weak.html#method.upgrade |
9e0c209e SL |
1423 | /// |
1424 | /// # Examples | |
1425 | /// | |
1426 | /// ``` | |
1427 | /// use std::rc::Weak; | |
1428 | /// | |
1429 | /// let empty: Weak<i64> = Default::default(); | |
1430 | /// assert!(empty.upgrade().is_none()); | |
1431 | /// ``` | |
a7813a04 XL |
1432 | fn default() -> Weak<T> { |
1433 | Weak::new() | |
9cc50fc6 SL |
1434 | } |
1435 | } | |
1436 | ||
8faf50e0 | 1437 | // NOTE: We checked_add here to deal with mem::forget safely. In particular |
c1a9b12d SL |
1438 | // if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then |
1439 | // you can free the allocation while outstanding Rcs (or Weaks) exist. | |
1440 | // We abort because this is such a degenerate scenario that we don't care about | |
1441 | // what happens -- no real program should ever experience this. | |
1442 | // | |
1443 | // This should have negligible overhead since you don't actually need to | |
1444 | // clone these much in Rust thanks to ownership and move-semantics. | |
1445 | ||
d9579d0f AL |
1446 | #[doc(hidden)] |
1447 | trait RcBoxPtr<T: ?Sized> { | |
1448 | fn inner(&self) -> &RcBox<T>; | |
1449 | ||
1450 | #[inline] | |
b039eaaf SL |
1451 | fn strong(&self) -> usize { |
1452 | self.inner().strong.get() | |
1453 | } | |
d9579d0f AL |
1454 | |
1455 | #[inline] | |
c1a9b12d | 1456 | fn inc_strong(&self) { |
b7449926 XL |
1457 | // We want to abort on overflow instead of dropping the value. |
1458 | // The reference count will never be zero when this is called; | |
1459 | // nevertheless, we insert an abort here to hint LLVM at | |
1460 | // an otherwise missed optimization. | |
1461 | if self.strong() == 0 || self.strong() == usize::max_value() { | |
1462 | unsafe { abort(); } | |
1463 | } | |
1464 | self.inner().strong.set(self.strong() + 1); | |
c1a9b12d | 1465 | } |
d9579d0f AL |
1466 | |
1467 | #[inline] | |
b039eaaf SL |
1468 | fn dec_strong(&self) { |
1469 | self.inner().strong.set(self.strong() - 1); | |
1470 | } | |
d9579d0f AL |
1471 | |
1472 | #[inline] | |
b039eaaf SL |
1473 | fn weak(&self) -> usize { |
1474 | self.inner().weak.get() | |
1475 | } | |
d9579d0f AL |
1476 | |
1477 | #[inline] | |
c1a9b12d | 1478 | fn inc_weak(&self) { |
b7449926 XL |
1479 | // We want to abort on overflow instead of dropping the value. |
1480 | // The reference count will never be zero when this is called; | |
1481 | // nevertheless, we insert an abort here to hint LLVM at | |
1482 | // an otherwise missed optimization. | |
1483 | if self.weak() == 0 || self.weak() == usize::max_value() { | |
1484 | unsafe { abort(); } | |
1485 | } | |
1486 | self.inner().weak.set(self.weak() + 1); | |
c1a9b12d | 1487 | } |
d9579d0f AL |
1488 | |
1489 | #[inline] | |
b039eaaf SL |
1490 | fn dec_weak(&self) { |
1491 | self.inner().weak.set(self.weak() - 1); | |
1492 | } | |
d9579d0f | 1493 | } |
1a4d82fc | 1494 | |
d9579d0f AL |
1495 | impl<T: ?Sized> RcBoxPtr<T> for Rc<T> { |
1496 | #[inline(always)] | |
1497 | fn inner(&self) -> &RcBox<T> { | |
1498 | unsafe { | |
7cac9316 | 1499 | self.ptr.as_ref() |
85aaf69f SL |
1500 | } |
1501 | } | |
1a4d82fc JJ |
1502 | } |
1503 | ||
8faf50e0 | 1504 | impl<T: ?Sized> RcBoxPtr<T> for RcBox<T> { |
d9579d0f AL |
1505 | #[inline(always)] |
1506 | fn inner(&self) -> &RcBox<T> { | |
8faf50e0 | 1507 | self |
85aaf69f | 1508 | } |
1a4d82fc JJ |
1509 | } |
1510 | ||
1511 | #[cfg(test)] | |
1a4d82fc | 1512 | mod tests { |
e9174d1e | 1513 | use super::{Rc, Weak}; |
c34b1796 | 1514 | use std::boxed::Box; |
1a4d82fc JJ |
1515 | use std::cell::RefCell; |
1516 | use std::option::Option; | |
3157f602 | 1517 | use std::option::Option::{None, Some}; |
1a4d82fc JJ |
1518 | use std::result::Result::{Err, Ok}; |
1519 | use std::mem::drop; | |
1520 | use std::clone::Clone; | |
92a42be0 | 1521 | use std::convert::From; |
1a4d82fc JJ |
1522 | |
1523 | #[test] | |
1524 | fn test_clone() { | |
85aaf69f | 1525 | let x = Rc::new(RefCell::new(5)); |
1a4d82fc JJ |
1526 | let y = x.clone(); |
1527 | *x.borrow_mut() = 20; | |
1528 | assert_eq!(*y.borrow(), 20); | |
1529 | } | |
1530 | ||
1531 | #[test] | |
1532 | fn test_simple() { | |
85aaf69f | 1533 | let x = Rc::new(5); |
1a4d82fc JJ |
1534 | assert_eq!(*x, 5); |
1535 | } | |
1536 | ||
1537 | #[test] | |
1538 | fn test_simple_clone() { | |
85aaf69f | 1539 | let x = Rc::new(5); |
1a4d82fc JJ |
1540 | let y = x.clone(); |
1541 | assert_eq!(*x, 5); | |
1542 | assert_eq!(*y, 5); | |
1543 | } | |
1544 | ||
1545 | #[test] | |
1546 | fn test_destructor() { | |
c34b1796 | 1547 | let x: Rc<Box<_>> = Rc::new(box 5); |
1a4d82fc JJ |
1548 | assert_eq!(**x, 5); |
1549 | } | |
1550 | ||
1551 | #[test] | |
1552 | fn test_live() { | |
85aaf69f | 1553 | let x = Rc::new(5); |
e9174d1e | 1554 | let y = Rc::downgrade(&x); |
1a4d82fc JJ |
1555 | assert!(y.upgrade().is_some()); |
1556 | } | |
1557 | ||
1558 | #[test] | |
1559 | fn test_dead() { | |
85aaf69f | 1560 | let x = Rc::new(5); |
e9174d1e | 1561 | let y = Rc::downgrade(&x); |
1a4d82fc JJ |
1562 | drop(x); |
1563 | assert!(y.upgrade().is_none()); | |
1564 | } | |
1565 | ||
1566 | #[test] | |
1567 | fn weak_self_cyclic() { | |
1568 | struct Cycle { | |
b039eaaf | 1569 | x: RefCell<Option<Weak<Cycle>>>, |
1a4d82fc JJ |
1570 | } |
1571 | ||
1572 | let a = Rc::new(Cycle { x: RefCell::new(None) }); | |
e9174d1e | 1573 | let b = Rc::downgrade(&a.clone()); |
1a4d82fc JJ |
1574 | *a.x.borrow_mut() = Some(b); |
1575 | ||
1576 | // hopefully we don't double-free (or leak)... | |
1577 | } | |
1578 | ||
1579 | #[test] | |
1580 | fn is_unique() { | |
85aaf69f | 1581 | let x = Rc::new(3); |
e9174d1e | 1582 | assert!(Rc::is_unique(&x)); |
1a4d82fc | 1583 | let y = x.clone(); |
e9174d1e | 1584 | assert!(!Rc::is_unique(&x)); |
1a4d82fc | 1585 | drop(y); |
e9174d1e SL |
1586 | assert!(Rc::is_unique(&x)); |
1587 | let w = Rc::downgrade(&x); | |
1588 | assert!(!Rc::is_unique(&x)); | |
1a4d82fc | 1589 | drop(w); |
e9174d1e | 1590 | assert!(Rc::is_unique(&x)); |
1a4d82fc JJ |
1591 | } |
1592 | ||
1593 | #[test] | |
1594 | fn test_strong_count() { | |
54a0048b | 1595 | let a = Rc::new(0); |
e9174d1e SL |
1596 | assert!(Rc::strong_count(&a) == 1); |
1597 | let w = Rc::downgrade(&a); | |
1598 | assert!(Rc::strong_count(&a) == 1); | |
1a4d82fc | 1599 | let b = w.upgrade().expect("upgrade of live rc failed"); |
e9174d1e SL |
1600 | assert!(Rc::strong_count(&b) == 2); |
1601 | assert!(Rc::strong_count(&a) == 2); | |
1a4d82fc JJ |
1602 | drop(w); |
1603 | drop(a); | |
e9174d1e | 1604 | assert!(Rc::strong_count(&b) == 1); |
1a4d82fc | 1605 | let c = b.clone(); |
e9174d1e SL |
1606 | assert!(Rc::strong_count(&b) == 2); |
1607 | assert!(Rc::strong_count(&c) == 2); | |
1a4d82fc JJ |
1608 | } |
1609 | ||
1610 | #[test] | |
1611 | fn test_weak_count() { | |
54a0048b | 1612 | let a = Rc::new(0); |
e9174d1e SL |
1613 | assert!(Rc::strong_count(&a) == 1); |
1614 | assert!(Rc::weak_count(&a) == 0); | |
1615 | let w = Rc::downgrade(&a); | |
1616 | assert!(Rc::strong_count(&a) == 1); | |
1617 | assert!(Rc::weak_count(&a) == 1); | |
1a4d82fc | 1618 | drop(w); |
e9174d1e SL |
1619 | assert!(Rc::strong_count(&a) == 1); |
1620 | assert!(Rc::weak_count(&a) == 0); | |
1a4d82fc | 1621 | let c = a.clone(); |
e9174d1e SL |
1622 | assert!(Rc::strong_count(&a) == 2); |
1623 | assert!(Rc::weak_count(&a) == 0); | |
1a4d82fc JJ |
1624 | drop(c); |
1625 | } | |
1626 | ||
1627 | #[test] | |
1628 | fn try_unwrap() { | |
85aaf69f | 1629 | let x = Rc::new(3); |
e9174d1e | 1630 | assert_eq!(Rc::try_unwrap(x), Ok(3)); |
85aaf69f | 1631 | let x = Rc::new(4); |
1a4d82fc | 1632 | let _y = x.clone(); |
e9174d1e | 1633 | assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); |
85aaf69f | 1634 | let x = Rc::new(5); |
e9174d1e SL |
1635 | let _w = Rc::downgrade(&x); |
1636 | assert_eq!(Rc::try_unwrap(x), Ok(5)); | |
1a4d82fc JJ |
1637 | } |
1638 | ||
476ff2be SL |
1639 | #[test] |
1640 | fn into_from_raw() { | |
1641 | let x = Rc::new(box "hello"); | |
1642 | let y = x.clone(); | |
1643 | ||
1644 | let x_ptr = Rc::into_raw(x); | |
1645 | drop(y); | |
1646 | unsafe { | |
1647 | assert_eq!(**x_ptr, "hello"); | |
1648 | ||
1649 | let x = Rc::from_raw(x_ptr); | |
1650 | assert_eq!(**x, "hello"); | |
1651 | ||
1652 | assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello")); | |
1653 | } | |
1654 | } | |
1655 | ||
ea8adc8c XL |
1656 | #[test] |
1657 | fn test_into_from_raw_unsized() { | |
1658 | use std::fmt::Display; | |
1659 | use std::string::ToString; | |
1660 | ||
1661 | let rc: Rc<str> = Rc::from("foo"); | |
1662 | ||
1663 | let ptr = Rc::into_raw(rc.clone()); | |
1664 | let rc2 = unsafe { Rc::from_raw(ptr) }; | |
1665 | ||
1666 | assert_eq!(unsafe { &*ptr }, "foo"); | |
1667 | assert_eq!(rc, rc2); | |
1668 | ||
8faf50e0 | 1669 | let rc: Rc<dyn Display> = Rc::new(123); |
ea8adc8c XL |
1670 | |
1671 | let ptr = Rc::into_raw(rc.clone()); | |
1672 | let rc2 = unsafe { Rc::from_raw(ptr) }; | |
1673 | ||
1674 | assert_eq!(unsafe { &*ptr }.to_string(), "123"); | |
1675 | assert_eq!(rc2.to_string(), "123"); | |
1676 | } | |
1677 | ||
1a4d82fc JJ |
1678 | #[test] |
1679 | fn get_mut() { | |
85aaf69f | 1680 | let mut x = Rc::new(3); |
e9174d1e | 1681 | *Rc::get_mut(&mut x).unwrap() = 4; |
85aaf69f | 1682 | assert_eq!(*x, 4); |
1a4d82fc | 1683 | let y = x.clone(); |
e9174d1e | 1684 | assert!(Rc::get_mut(&mut x).is_none()); |
1a4d82fc | 1685 | drop(y); |
e9174d1e SL |
1686 | assert!(Rc::get_mut(&mut x).is_some()); |
1687 | let _w = Rc::downgrade(&x); | |
1688 | assert!(Rc::get_mut(&mut x).is_none()); | |
1a4d82fc JJ |
1689 | } |
1690 | ||
1691 | #[test] | |
1692 | fn test_cowrc_clone_make_unique() { | |
85aaf69f | 1693 | let mut cow0 = Rc::new(75); |
1a4d82fc JJ |
1694 | let mut cow1 = cow0.clone(); |
1695 | let mut cow2 = cow1.clone(); | |
1696 | ||
e9174d1e SL |
1697 | assert!(75 == *Rc::make_mut(&mut cow0)); |
1698 | assert!(75 == *Rc::make_mut(&mut cow1)); | |
1699 | assert!(75 == *Rc::make_mut(&mut cow2)); | |
1a4d82fc | 1700 | |
e9174d1e SL |
1701 | *Rc::make_mut(&mut cow0) += 1; |
1702 | *Rc::make_mut(&mut cow1) += 2; | |
1703 | *Rc::make_mut(&mut cow2) += 3; | |
1a4d82fc JJ |
1704 | |
1705 | assert!(76 == *cow0); | |
1706 | assert!(77 == *cow1); | |
1707 | assert!(78 == *cow2); | |
1708 | ||
1709 | // none should point to the same backing memory | |
1710 | assert!(*cow0 != *cow1); | |
1711 | assert!(*cow0 != *cow2); | |
1712 | assert!(*cow1 != *cow2); | |
1713 | } | |
1714 | ||
1715 | #[test] | |
1716 | fn test_cowrc_clone_unique2() { | |
85aaf69f | 1717 | let mut cow0 = Rc::new(75); |
1a4d82fc JJ |
1718 | let cow1 = cow0.clone(); |
1719 | let cow2 = cow1.clone(); | |
1720 | ||
1721 | assert!(75 == *cow0); | |
1722 | assert!(75 == *cow1); | |
1723 | assert!(75 == *cow2); | |
1724 | ||
e9174d1e | 1725 | *Rc::make_mut(&mut cow0) += 1; |
1a4d82fc JJ |
1726 | |
1727 | assert!(76 == *cow0); | |
1728 | assert!(75 == *cow1); | |
1729 | assert!(75 == *cow2); | |
1730 | ||
1731 | // cow1 and cow2 should share the same contents | |
1732 | // cow0 should have a unique reference | |
1733 | assert!(*cow0 != *cow1); | |
1734 | assert!(*cow0 != *cow2); | |
1735 | assert!(*cow1 == *cow2); | |
1736 | } | |
1737 | ||
1738 | #[test] | |
1739 | fn test_cowrc_clone_weak() { | |
85aaf69f | 1740 | let mut cow0 = Rc::new(75); |
e9174d1e | 1741 | let cow1_weak = Rc::downgrade(&cow0); |
1a4d82fc JJ |
1742 | |
1743 | assert!(75 == *cow0); | |
1744 | assert!(75 == *cow1_weak.upgrade().unwrap()); | |
1745 | ||
e9174d1e | 1746 | *Rc::make_mut(&mut cow0) += 1; |
1a4d82fc JJ |
1747 | |
1748 | assert!(76 == *cow0); | |
1749 | assert!(cow1_weak.upgrade().is_none()); | |
1750 | } | |
1751 | ||
1752 | #[test] | |
1753 | fn test_show() { | |
85aaf69f SL |
1754 | let foo = Rc::new(75); |
1755 | assert_eq!(format!("{:?}", foo), "75"); | |
1a4d82fc JJ |
1756 | } |
1757 | ||
62682a34 SL |
1758 | #[test] |
1759 | fn test_unsized() { | |
1760 | let foo: Rc<[i32]> = Rc::new([1, 2, 3]); | |
1761 | assert_eq!(foo, foo.clone()); | |
1762 | } | |
92a42be0 SL |
1763 | |
1764 | #[test] | |
1765 | fn test_from_owned() { | |
1766 | let foo = 123; | |
1767 | let foo_rc = Rc::from(foo); | |
1768 | assert!(123 == *foo_rc); | |
1769 | } | |
9cc50fc6 SL |
1770 | |
1771 | #[test] | |
1772 | fn test_new_weak() { | |
1773 | let foo: Weak<usize> = Weak::new(); | |
1774 | assert!(foo.upgrade().is_none()); | |
1775 | } | |
9e0c209e SL |
1776 | |
1777 | #[test] | |
1778 | fn test_ptr_eq() { | |
1779 | let five = Rc::new(5); | |
1780 | let same_five = five.clone(); | |
1781 | let other_five = Rc::new(5); | |
1782 | ||
1783 | assert!(Rc::ptr_eq(&five, &same_five)); | |
1784 | assert!(!Rc::ptr_eq(&five, &other_five)); | |
1785 | } | |
3b2f2976 XL |
1786 | |
1787 | #[test] | |
1788 | fn test_from_str() { | |
1789 | let r: Rc<str> = Rc::from("foo"); | |
1790 | ||
1791 | assert_eq!(&r[..], "foo"); | |
1792 | } | |
1793 | ||
1794 | #[test] | |
1795 | fn test_copy_from_slice() { | |
1796 | let s: &[u32] = &[1, 2, 3]; | |
1797 | let r: Rc<[u32]> = Rc::from(s); | |
1798 | ||
1799 | assert_eq!(&r[..], [1, 2, 3]); | |
1800 | } | |
1801 | ||
1802 | #[test] | |
1803 | fn test_clone_from_slice() { | |
1804 | #[derive(Clone, Debug, Eq, PartialEq)] | |
1805 | struct X(u32); | |
1806 | ||
1807 | let s: &[X] = &[X(1), X(2), X(3)]; | |
1808 | let r: Rc<[X]> = Rc::from(s); | |
1809 | ||
1810 | assert_eq!(&r[..], s); | |
1811 | } | |
1812 | ||
1813 | #[test] | |
1814 | #[should_panic] | |
1815 | fn test_clone_from_slice_panic() { | |
1816 | use std::string::{String, ToString}; | |
1817 | ||
1818 | struct Fail(u32, String); | |
1819 | ||
1820 | impl Clone for Fail { | |
1821 | fn clone(&self) -> Fail { | |
1822 | if self.0 == 2 { | |
1823 | panic!(); | |
1824 | } | |
1825 | Fail(self.0, self.1.clone()) | |
1826 | } | |
1827 | } | |
1828 | ||
1829 | let s: &[Fail] = &[ | |
1830 | Fail(0, "foo".to_string()), | |
1831 | Fail(1, "bar".to_string()), | |
1832 | Fail(2, "baz".to_string()), | |
1833 | ]; | |
1834 | ||
1835 | // Should panic, but not cause memory corruption | |
1836 | let _r: Rc<[Fail]> = Rc::from(s); | |
1837 | } | |
1838 | ||
1839 | #[test] | |
1840 | fn test_from_box() { | |
1841 | let b: Box<u32> = box 123; | |
1842 | let r: Rc<u32> = Rc::from(b); | |
1843 | ||
1844 | assert_eq!(*r, 123); | |
1845 | } | |
1846 | ||
1847 | #[test] | |
1848 | fn test_from_box_str() { | |
1849 | use std::string::String; | |
1850 | ||
1851 | let s = String::from("foo").into_boxed_str(); | |
1852 | let r: Rc<str> = Rc::from(s); | |
1853 | ||
1854 | assert_eq!(&r[..], "foo"); | |
1855 | } | |
1856 | ||
1857 | #[test] | |
1858 | fn test_from_box_slice() { | |
1859 | let s = vec![1, 2, 3].into_boxed_slice(); | |
1860 | let r: Rc<[u32]> = Rc::from(s); | |
1861 | ||
1862 | assert_eq!(&r[..], [1, 2, 3]); | |
1863 | } | |
1864 | ||
1865 | #[test] | |
1866 | fn test_from_box_trait() { | |
1867 | use std::fmt::Display; | |
1868 | use std::string::ToString; | |
1869 | ||
8faf50e0 XL |
1870 | let b: Box<dyn Display> = box 123; |
1871 | let r: Rc<dyn Display> = Rc::from(b); | |
3b2f2976 XL |
1872 | |
1873 | assert_eq!(r.to_string(), "123"); | |
1874 | } | |
1875 | ||
1876 | #[test] | |
1877 | fn test_from_box_trait_zero_sized() { | |
1878 | use std::fmt::Debug; | |
1879 | ||
8faf50e0 XL |
1880 | let b: Box<dyn Debug> = box (); |
1881 | let r: Rc<dyn Debug> = Rc::from(b); | |
3b2f2976 XL |
1882 | |
1883 | assert_eq!(format!("{:?}", r), "()"); | |
1884 | } | |
1885 | ||
1886 | #[test] | |
1887 | fn test_from_vec() { | |
1888 | let v = vec![1, 2, 3]; | |
1889 | let r: Rc<[u32]> = Rc::from(v); | |
1890 | ||
1891 | assert_eq!(&r[..], [1, 2, 3]); | |
1892 | } | |
ea8adc8c XL |
1893 | |
1894 | #[test] | |
1895 | fn test_downcast() { | |
1896 | use std::any::Any; | |
1897 | ||
8faf50e0 XL |
1898 | let r1: Rc<dyn Any> = Rc::new(i32::max_value()); |
1899 | let r2: Rc<dyn Any> = Rc::new("abc"); | |
ea8adc8c XL |
1900 | |
1901 | assert!(r1.clone().downcast::<u32>().is_err()); | |
1902 | ||
1903 | let r1i32 = r1.downcast::<i32>(); | |
1904 | assert!(r1i32.is_ok()); | |
1905 | assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value())); | |
1906 | ||
1907 | assert!(r2.clone().downcast::<i32>().is_err()); | |
1908 | ||
1909 | let r2str = r2.downcast::<&'static str>(); | |
1910 | assert!(r2str.is_ok()); | |
1911 | assert_eq!(r2str.unwrap(), Rc::new("abc")); | |
1912 | } | |
1a4d82fc | 1913 | } |
e9174d1e | 1914 | |
92a42be0 | 1915 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 1916 | impl<T: ?Sized> borrow::Borrow<T> for Rc<T> { |
b039eaaf SL |
1917 | fn borrow(&self) -> &T { |
1918 | &**self | |
1919 | } | |
1920 | } | |
1921 | ||
1922 | #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] | |
1923 | impl<T: ?Sized> AsRef<T> for Rc<T> { | |
1924 | fn as_ref(&self) -> &T { | |
1925 | &**self | |
1926 | } | |
e9174d1e | 1927 | } |
b7449926 | 1928 | |
0731742a | 1929 | #[stable(feature = "pin", since = "1.33.0")] |
b7449926 | 1930 | impl<T: ?Sized> Unpin for Rc<T> { } |