From 56ee60901737ef93b16ff9a862337a1f677fc3a1 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Wed, 7 Dec 2022 02:29:46 -0500 Subject: [PATCH] Implement `Fn` traits for `Rc` and `Arc` These use the same semantics as the implementations for `&F` by only covering `F: Fn`. This change enables passing reference-counted closures to functions that expect `Fn + 'static` or `Fn + Clone`. --- library/alloc/src/rc.rs | 23 +++++++++++++++++++++++ library/alloc/src/sync.rs | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 38e31b1802a42..5f1a7a9a281d0 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1555,6 +1555,29 @@ impl Deref for Rc { } } +#[stable(feature = "rc_closure_impls", since = "CURRENT_RUSTC_VERSION")] +impl + ?Sized> Fn for Rc { + extern "rust-call" fn call(&self, args: Args) -> Self::Output { + >::call(self, args) + } +} + +#[stable(feature = "rc_closure_impls", since = "CURRENT_RUSTC_VERSION")] +impl + ?Sized> FnMut for Rc { + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { + >::call(self, args) + } +} + +#[stable(feature = "rc_closure_impls", since = "CURRENT_RUSTC_VERSION")] +impl + ?Sized> FnOnce for Rc { + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output { + >::call(&self, args) + } +} + #[unstable(feature = "receiver_trait", issue = "none")] impl Receiver for Rc {} diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index f7dc4d1094ca3..31910bea18fd0 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1392,6 +1392,29 @@ impl Deref for Arc { } } +#[stable(feature = "rc_closure_impls", since = "CURRENT_RUSTC_VERSION")] +impl + ?Sized> Fn for Arc { + extern "rust-call" fn call(&self, args: Args) -> Self::Output { + >::call(self, args) + } +} + +#[stable(feature = "rc_closure_impls", since = "CURRENT_RUSTC_VERSION")] +impl + ?Sized> FnMut for Arc { + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { + >::call(self, args) + } +} + +#[stable(feature = "rc_closure_impls", since = "CURRENT_RUSTC_VERSION")] +impl + ?Sized> FnOnce for Arc { + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output { + >::call(&self, args) + } +} + #[unstable(feature = "receiver_trait", issue = "none")] impl Receiver for Arc {}