From c856e1477710beca97fe3e155f20ee403d6e6a71 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 11 Mar 2018 02:43:38 +0100 Subject: [PATCH 1/2] impl Fn/FnMut/FnOnce for Arc/Rc" --- src/liballoc/arc.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++ src/liballoc/rc.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 6a77bf64baee5..b0eaa27cb083a 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -1413,6 +1413,70 @@ impl From> for Arc<[T]> { } } +mod fn_impls { + use super::Arc; + + #[stable(feature = "shared_fn_impls", since = "1.26.0")] + impl> Fn for Arc { + extern "rust-call" fn call(&self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "shared_fn_impls", since = "1.26.0")] + impl> FnMut for Arc { + extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "shared_fn_impls", since = "1.26.0")] + impl> FnOnce for Arc { + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: A) -> F::Output { + (&*self).call(args) + } + } + + #[cfg(test)] + mod tests { + #[test] + fn is_fn() { + use_fn(Arc::new(|x| x + 1)); + } + + #[test] + fn is_fn_mut() { + use_fn_mut(Arc::new(|x| x + 1)); + } + + #[test] + fn is_fn_once() { + use_fn_once(Arc::new(|x| x + 1)); + } + + #[test] + fn can_dyn_dispatch() { + let dyn_dispatch: Arc u8> = Arc::new(|x| x + 1); + use_fn(dyn_dispatch); + } + + fn use_fn_once u8>(fun: F) { + assert_eq!(2, fun(1)); + } + + fn use_fn_mut u8>(mut fun: F) { + assert_eq!(2, fun(1)); + assert_eq!(3, fun(2)); + } + + fn use_fn u8>(fun: F) { + assert_eq!(2, fun(1)); + } + } +} + #[cfg(test)] mod tests { use std::boxed::Box; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1fa5d34cb5787..02d7cbe6f86f6 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1388,6 +1388,70 @@ impl RcBoxPtr for Weak { } } +mod fn_impls { + use super::Rc; + + #[stable(feature = "shared_fn_impls", since = "1.26.0")] + impl> Fn for Rc { + extern "rust-call" fn call(&self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "shared_fn_impls", since = "1.26.0")] + impl> FnMut for Rc { + extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "shared_fn_impls", since = "1.26.0")] + impl> FnOnce for Rc { + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: A) -> F::Output { + (&*self).call(args) + } + } + + #[cfg(test)] + mod tests { + #[test] + fn is_fn() { + use_fn(Rc::new(|x| x + 1)); + } + + #[test] + fn is_fn_mut() { + use_fn_mut(Rc::new(|x| x + 1)); + } + + #[test] + fn is_fn_once() { + use_fn_once(Rc::new(|x| x + 1)); + } + + #[test] + fn can_dyn_dispatch() { + let dyn_dispatch: Rc u8> = Rc::new(|x| x + 1); + use_fn(dyn_dispatch); + } + + fn use_fn_once u8>(fun: F) { + assert_eq!(2, fun(1)); + } + + fn use_fn_mut u8>(mut fun: F) { + assert_eq!(2, fun(1)); + assert_eq!(3, fun(2)); + } + + fn use_fn u8>(fun: F) { + assert_eq!(2, fun(1)); + } + } +} + #[cfg(test)] mod tests { use super::{Rc, Weak}; From b0e188e89d85b16ee4acae9b2e9a750ca9a9f83f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 21 Mar 2018 06:19:59 +0100 Subject: [PATCH 2/2] Fn for Arc/Rc - fix build errors --- src/liballoc/arc.rs | 2 ++ src/liballoc/lib.rs | 3 ++- src/liballoc/rc.rs | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index b0eaa27cb083a..69bd6a17e91c1 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -1441,6 +1441,8 @@ mod fn_impls { #[cfg(test)] mod tests { + use super::Arc; + #[test] fn is_fn() { use_fn(Arc::new(|x| x + 1)); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index f914b1a93a916..3bca65b8cf6e1 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -125,8 +125,9 @@ #![feature(exact_chunks)] #![feature(pointer_methods)] #![feature(inclusive_range_fields)] +#![feature(fn_traits)] -#![cfg_attr(not(test), feature(fn_traits, placement_new_protocol, swap_with_slice, i128))] +#![cfg_attr(not(test), feature(placement_new_protocol, swap_with_slice, i128))] #![cfg_attr(test, feature(test, box_heap))] // Allow testing this library diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 02d7cbe6f86f6..8a07d73a2c0b3 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1416,6 +1416,8 @@ mod fn_impls { #[cfg(test)] mod tests { + use super::Rc; + #[test] fn is_fn() { use_fn(Rc::new(|x| x + 1));