Skip to content

Commit 05ec7c1

Browse files
committed
Add Adopt::try_adopt
1 parent 009bf34 commit 05ec7c1

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/adopt.rs

+30-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::fmt;
12
use core::ptr;
23

34
use crate::link::Link;
@@ -13,6 +14,21 @@ mod sealed {
1314
impl<T> Sealed for Rc<T> {}
1415
}
1516

17+
/// The error type for `try_adopt` methods.
18+
///
19+
/// See [`Adopt::try_adopt`] for more information.
20+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
21+
pub struct AdoptError(());
22+
23+
#[cfg(feature = "std")]
24+
impl std::error::Error for AdoptError {}
25+
26+
impl fmt::Display for AdoptError {
27+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28+
f.write_str("Rc adoption failed because the Rc does not own a pointer to the adoptee")
29+
}
30+
}
31+
1632
/// Build a graph of linked [`Rc`] smart pointers to enable busting cycles on
1733
/// drop.
1834
///
@@ -34,12 +50,20 @@ mod sealed {
3450
///
3551
/// [`adopt_unchecked`]: Adopt::adopt_unchecked
3652
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
37-
pub unsafe trait Adopt: sealed::Sealed {
53+
pub unsafe trait Adopt: sealed::Sealed + Sized {
3854
/// The smart pointer's inner owned value.
3955
type Inner;
4056

4157
/// TODO: document me!
42-
fn adopt(this: &mut Self, other: &Self)
58+
fn adopt(this: &mut Self, other: &Self) -> Self
59+
where
60+
Self::Inner: Trace,
61+
{
62+
Self::try_adopt(this, other).unwrap_or_else(|err| panic!("{}", err))
63+
}
64+
65+
/// TODO: document me!
66+
fn try_adopt(this: &mut Self, other: &Self) -> Result<Self, AdoptError>
4367
where
4468
Self::Inner: Trace;
4569

@@ -92,7 +116,7 @@ unsafe impl<T> Adopt for Rc<T> {
92116
type Inner = T;
93117

94118
/// TODO: document me!
95-
fn adopt(this: &mut Self, other: &Self)
119+
fn try_adopt(this: &mut Self, other: &Self) -> Result<Self, AdoptError>
96120
where
97121
Self::Inner: Trace,
98122
{
@@ -125,6 +149,9 @@ unsafe impl<T> Adopt for Rc<T> {
125149
unsafe {
126150
Self::adopt_unchecked(this, &node);
127151
}
152+
Ok(node)
153+
} else {
154+
Err(AdoptError(()))
128155
}
129156
}
130157

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ mod trace;
145145
pub mod implementing_self_referential_data_structures;
146146

147147
pub use adopt::Adopt;
148+
pub use adopt::AdoptError;
148149
pub use rc::Rc;
149150
pub use rc::Weak;
150151
pub use trace::Trace;

0 commit comments

Comments
 (0)