diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index ccf2e2768d1a9..fe18ab7d15a20 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -1414,6 +1414,72 @@ 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 { + use super::Arc; + + #[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/lib.rs b/src/liballoc/lib.rs index da26e7c852c46..9b23839ce72b2 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -121,9 +121,11 @@ #![feature(exact_chunks)] #![feature(pointer_methods)] #![feature(inclusive_range_fields)] +#![feature(fn_traits)] + #![cfg_attr(stage0, feature(generic_param_attrs))] -#![cfg_attr(not(test), feature(fn_traits, swap_with_slice, i128))] +#![cfg_attr(not(test), feature(swap_with_slice, i128))] #![cfg_attr(test, feature(test))] // Allow testing this library diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 8bdc57f96a6d5..9abe7e2324ffc 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1389,6 +1389,72 @@ 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 { + use super::Rc; + + #[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};