Skip to content

Commit 9fa35e3

Browse files
committed
Add [A]RcBorrow -> Weak conversion without strong clone
1 parent 4d54f90 commit 9fa35e3

File tree

3 files changed

+57
-42
lines changed

3 files changed

+57
-42
lines changed

Cargo.lock

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/rc-borrow/build.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
fn main() {
22
let cfg = autocfg::new();
3-
cfg.emit_expression_cfg("std::sync::Arc::as_raw", "has_Arc__into_raw");
4-
cfg.emit_expression_cfg("std::sync::Arc::clone_raw", "has_Arc__clone_raw");
5-
cfg.emit_expression_cfg("std::rc::Rc::as_raw", "has_Rc__into_raw");
6-
cfg.emit_expression_cfg("std::rc::Rc::clone_raw", "has_Rc__clone_raw");
3+
cfg.emit_expression_cfg("std::sync::Arc::as_ptr", "has_Arc__as_ptr");
4+
cfg.emit_expression_cfg("std::rc::Rc::as_ptr", "has_Rc__as_ptr");
75
autocfg::rerun_path("build.rs");
86
}

crates/rc-borrow/src/lib.rs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ use std::{
3535
panic::{RefUnwindSafe, UnwindSafe},
3636
};
3737
use {
38-
alloc::{rc::Rc, sync::Arc},
38+
alloc::{
39+
rc::{self, Rc},
40+
sync::{self, Arc},
41+
},
3942
core::{
4043
borrow::Borrow,
4144
cmp::Ordering,
@@ -55,59 +58,68 @@ use {
5558
/// See https://internals.rust-lang.org/t/_/11463/11 for why these are important.
5659
/// By using a trait here, we can more easily switch when these functions are available.
5760
trait RawRc<T: ?Sized> {
61+
type Weak;
62+
5863
//noinspection RsSelfConvention
5964
fn as_raw(this: &Self) -> *const T;
65+
6066
/// # Safety
6167
///
6268
/// This pointer must have come from [`RawRc::as_raw`] or `into_raw`.
6369
unsafe fn clone_raw(this: *const T) -> Self;
70+
71+
unsafe fn downgrade_raw(this: *const T) -> Self::Weak;
6472
}
6573

6674
impl<T: ?Sized> RawRc<T> for Arc<T> {
75+
type Weak = sync::Weak<T>;
76+
6777
#[rustfmt::skip]
6878
#[inline(always)]
6979
fn as_raw(this: &Self) -> *const T {
70-
#[cfg(not(has_Arc__as_raw))] {
80+
#[cfg(not(has_Arc__as_ptr))] {
7181
Arc::into_raw(unsafe { ptr::read(this) })
7282
}
7383
#[cfg(has_Arc__as_raw)] {
74-
Arc::as_raw(this)
84+
Arc::as_ptr(this)
7585
}
7686
}
7787

78-
#[rustfmt::skip]
7988
#[inline(always)]
8089
unsafe fn clone_raw(this: *const T) -> Self {
81-
#[cfg(not(has_Arc__clone_raw))] {
82-
Arc::clone(&ManuallyDrop::new(Arc::from_raw(this)))
83-
}
84-
#[cfg(has_Arc__clone_raw)] {
85-
Arc::clone_raw(this)
86-
}
90+
Arc::clone(&ManuallyDrop::new(Arc::from_raw(this)))
91+
}
92+
93+
#[inline(always)]
94+
unsafe fn downgrade_raw(this: *const T) -> sync::Weak<T> {
95+
let this = ManuallyDrop::new(Arc::from_raw(this));
96+
Arc::downgrade(&this)
8797
}
8898
}
8999

90100
impl<T: ?Sized> RawRc<T> for Rc<T> {
101+
type Weak = rc::Weak<T>;
102+
91103
#[rustfmt::skip]
92104
#[inline(always)]
93105
fn as_raw(this: &Self) -> *const T {
94-
#[cfg(not(has_Rc__as_raw))] {
106+
#[cfg(not(has_Rc__as_ptr))] {
95107
Rc::into_raw(unsafe { ptr::read(this) })
96108
}
97-
#[cfg(has_Rc__as_raw)] {
98-
Rc::as_raw(this)
109+
#[cfg(has_Rc__as_ptr)] {
110+
Rc::as_ptr(this)
99111
}
100112
}
101113

102-
#[rustfmt::skip]
103114
#[inline(always)]
104115
unsafe fn clone_raw(this: *const T) -> Self {
105-
#[cfg(not(has_Rc__clone_raw))] {
106-
Rc::clone(&ManuallyDrop::new(Rc::from_raw(this)))
107-
}
108-
#[cfg(has_Rc__clone_raw)] {
109-
Rc::clone_raw(this)
110-
}
116+
Rc::clone(&ManuallyDrop::new(Rc::from_raw(this)))
117+
}
118+
119+
#[inline(always)]
120+
unsafe fn downgrade_raw(this: *const T) -> rc::Weak<T> {
121+
let this = ManuallyDrop::new(Rc::from_raw(this));
122+
Rc::downgrade(&this)
111123
}
112124
}
113125

@@ -120,7 +132,7 @@ macro_rules! doc_comment {
120132
}
121133

122134
macro_rules! rc_borrow {
123-
($($(#[$m:meta])* $vis:vis struct $RcBorrow:ident = &$Rc:ident;)*) => {$(
135+
($($(#[$m:meta])* $vis:vis struct $RcBorrow:ident = &$Rc:ident ($rc:ident);)*) => {$(
124136
$(#[$m])*
125137
$vis struct $RcBorrow<'a, T: ?Sized> {
126138
raw: ptr::NonNull<T>,
@@ -147,6 +159,11 @@ macro_rules! rc_borrow {
147159
unsafe { <$Rc<T> as RawRc<T>>::clone_raw(this.raw.as_ptr()) }
148160
}
149161

162+
/// Convert this borrowed pointer into a weak pointer.
163+
$vis fn weaken(this: Self) -> $rc::Weak<T> {
164+
unsafe { <$Rc<T> as RawRc<T>>::downgrade_raw(this.raw.as_ptr()) }
165+
}
166+
150167
/// Convert this borrowed pointer into a standard reference.
151168
///
152169
/// This gives you a long-lived reference,
@@ -377,10 +394,10 @@ rc_borrow! {
377394
///
378395
/// This type is guaranteed to have the same repr as `&T`.
379396
#[repr(transparent)]
380-
pub struct ArcBorrow = &Arc;
397+
pub struct ArcBorrow = &Arc (sync);
381398
/// Borrowed version of [`Rc`].
382399
///
383400
/// This type is guaranteed to have the same repr as `&T`.
384401
#[repr(transparent)]
385-
pub struct RcBorrow = &Rc;
402+
pub struct RcBorrow = &Rc (rc);
386403
}

0 commit comments

Comments
 (0)