Skip to content

Commit 79aec55

Browse files
committed
Implement Fn traits for Rc/Arc
1 parent 763f923 commit 79aec55

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

src/liballoc/arc.rs

+35
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,35 @@ impl<T: ?Sized + Hash> Hash for Arc<T> {
936936
}
937937
}
938938

939+
#[stable(feature = "fn_smart_ptr", since = "1.11.0")]
940+
impl<I, F: ?Sized> Fn<I> for Arc<F>
941+
where F: Fn<I>
942+
{
943+
extern "rust-call" fn call(&self, args: I) -> Self::Output {
944+
(&**self).call(args)
945+
}
946+
}
947+
948+
#[stable(feature = "fn_smart_ptr", since = "1.11.0")]
949+
impl<I, F: ?Sized> FnMut<I> for Arc<F>
950+
where F: Fn<I>
951+
{
952+
extern "rust-call" fn call_mut(&mut self, args: I) -> Self::Output {
953+
self.call(args)
954+
}
955+
}
956+
957+
#[stable(feature = "fn_smart_ptr", since = "1.11.0")]
958+
impl<I, F: ?Sized> FnOnce<I> for Arc<F>
959+
where F: Fn<I>
960+
{
961+
type Output = F::Output;
962+
extern "rust-call" fn call_once(self, args: I) -> Self::Output {
963+
self.call(args)
964+
}
965+
}
966+
967+
939968
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
940969
impl<T> From<T> for Arc<T> {
941970
fn from(t: T) -> Self {
@@ -1172,6 +1201,12 @@ mod tests {
11721201
assert_eq!(format!("{:?}", a), "5");
11731202
}
11741203

1204+
#[test]
1205+
fn test_fn() {
1206+
let f = Arc::new(|i: i32| -> i32 { i + 1 });
1207+
assert_eq!(Some(1).map(f), Some(2));
1208+
}
1209+
11751210
// Make sure deriving works with Arc<T>
11761211
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
11771212
struct Foo {

src/liballoc/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@
9090
#![feature(unique)]
9191
#![feature(unsafe_no_drop_flag, filling_drop)]
9292
#![feature(unsize)]
93+
#![feature(fn_traits)]
9394

94-
#![cfg_attr(not(test), feature(raw, fn_traits, placement_new_protocol))]
95+
#![cfg_attr(not(test), feature(raw, placement_new_protocol))]
9596
#![cfg_attr(test, feature(test, box_heap))]
9697

9798
// Allow testing this library

src/liballoc/rc.rs

+34
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,34 @@ impl<T: ?Sized> fmt::Pointer for Rc<T> {
693693
}
694694
}
695695

696+
#[stable(feature = "fn_smart_ptr", since = "1.11.0")]
697+
impl<I, F: ?Sized> Fn<I> for Rc<F>
698+
where F: Fn<I>
699+
{
700+
extern "rust-call" fn call(&self, args: I) -> Self::Output {
701+
(&**self).call(args)
702+
}
703+
}
704+
705+
#[stable(feature = "fn_smart_ptr", since = "1.11.0")]
706+
impl<I, F: ?Sized> FnMut<I> for Rc<F>
707+
where F: Fn<I>
708+
{
709+
extern "rust-call" fn call_mut(&mut self, args: I) -> Self::Output {
710+
self.call(args)
711+
}
712+
}
713+
714+
#[stable(feature = "fn_smart_ptr", since = "1.11.0")]
715+
impl<I, F: ?Sized> FnOnce<I> for Rc<F>
716+
where F: Fn<I>
717+
{
718+
type Output = F::Output;
719+
extern "rust-call" fn call_once(self, args: I) -> Self::Output {
720+
self.call(args)
721+
}
722+
}
723+
696724
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
697725
impl<T> From<T> for Rc<T> {
698726
fn from(t: T) -> Self {
@@ -1137,6 +1165,12 @@ mod tests {
11371165
assert_eq!(format!("{:?}", foo), "75");
11381166
}
11391167

1168+
#[test]
1169+
fn test_fn() {
1170+
let f = Rc::new(|i: i32| -> i32 { i + 1 });
1171+
assert_eq!(Some(1).map(f), Some(2));
1172+
}
1173+
11401174
#[test]
11411175
fn test_unsized() {
11421176
let foo: Rc<[i32]> = Rc::new([1, 2, 3]);

0 commit comments

Comments
 (0)