Skip to content

Commit c856e14

Browse files
committed
impl Fn/FnMut/FnOnce for Arc/Rc"
1 parent 2f0e6a3 commit c856e14

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

src/liballoc/arc.rs

+64
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,70 @@ impl<T> From<Vec<T>> for Arc<[T]> {
14131413
}
14141414
}
14151415

1416+
mod fn_impls {
1417+
use super::Arc;
1418+
1419+
#[stable(feature = "shared_fn_impls", since = "1.26.0")]
1420+
impl<A, F: ?Sized + Fn<A>> Fn<A> for Arc<F> {
1421+
extern "rust-call" fn call(&self, args: A) -> F::Output {
1422+
(**self).call(args)
1423+
}
1424+
}
1425+
1426+
#[stable(feature = "shared_fn_impls", since = "1.26.0")]
1427+
impl<A, F: ?Sized + Fn<A>> FnMut<A> for Arc<F> {
1428+
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
1429+
(**self).call(args)
1430+
}
1431+
}
1432+
1433+
#[stable(feature = "shared_fn_impls", since = "1.26.0")]
1434+
impl<A, F: ?Sized + Fn<A>> FnOnce<A> for Arc<F> {
1435+
type Output = F::Output;
1436+
1437+
extern "rust-call" fn call_once(self, args: A) -> F::Output {
1438+
(&*self).call(args)
1439+
}
1440+
}
1441+
1442+
#[cfg(test)]
1443+
mod tests {
1444+
#[test]
1445+
fn is_fn() {
1446+
use_fn(Arc::new(|x| x + 1));
1447+
}
1448+
1449+
#[test]
1450+
fn is_fn_mut() {
1451+
use_fn_mut(Arc::new(|x| x + 1));
1452+
}
1453+
1454+
#[test]
1455+
fn is_fn_once() {
1456+
use_fn_once(Arc::new(|x| x + 1));
1457+
}
1458+
1459+
#[test]
1460+
fn can_dyn_dispatch() {
1461+
let dyn_dispatch: Arc<Fn(u8) -> u8> = Arc::new(|x| x + 1);
1462+
use_fn(dyn_dispatch);
1463+
}
1464+
1465+
fn use_fn_once<F: FnOnce(u8) -> u8>(fun: F) {
1466+
assert_eq!(2, fun(1));
1467+
}
1468+
1469+
fn use_fn_mut<F: FnMut(u8) -> u8>(mut fun: F) {
1470+
assert_eq!(2, fun(1));
1471+
assert_eq!(3, fun(2));
1472+
}
1473+
1474+
fn use_fn<F: Fn(u8) -> u8>(fun: F) {
1475+
assert_eq!(2, fun(1));
1476+
}
1477+
}
1478+
}
1479+
14161480
#[cfg(test)]
14171481
mod tests {
14181482
use std::boxed::Box;

src/liballoc/rc.rs

+64
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,70 @@ impl<T: ?Sized> RcBoxPtr<T> for Weak<T> {
13881388
}
13891389
}
13901390

1391+
mod fn_impls {
1392+
use super::Rc;
1393+
1394+
#[stable(feature = "shared_fn_impls", since = "1.26.0")]
1395+
impl<A, F: ?Sized + Fn<A>> Fn<A> for Rc<F> {
1396+
extern "rust-call" fn call(&self, args: A) -> F::Output {
1397+
(**self).call(args)
1398+
}
1399+
}
1400+
1401+
#[stable(feature = "shared_fn_impls", since = "1.26.0")]
1402+
impl<A, F: ?Sized + Fn<A>> FnMut<A> for Rc<F> {
1403+
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
1404+
(**self).call(args)
1405+
}
1406+
}
1407+
1408+
#[stable(feature = "shared_fn_impls", since = "1.26.0")]
1409+
impl<A, F: ?Sized + Fn<A>> FnOnce<A> for Rc<F> {
1410+
type Output = F::Output;
1411+
1412+
extern "rust-call" fn call_once(self, args: A) -> F::Output {
1413+
(&*self).call(args)
1414+
}
1415+
}
1416+
1417+
#[cfg(test)]
1418+
mod tests {
1419+
#[test]
1420+
fn is_fn() {
1421+
use_fn(Rc::new(|x| x + 1));
1422+
}
1423+
1424+
#[test]
1425+
fn is_fn_mut() {
1426+
use_fn_mut(Rc::new(|x| x + 1));
1427+
}
1428+
1429+
#[test]
1430+
fn is_fn_once() {
1431+
use_fn_once(Rc::new(|x| x + 1));
1432+
}
1433+
1434+
#[test]
1435+
fn can_dyn_dispatch() {
1436+
let dyn_dispatch: Rc<Fn(u8) -> u8> = Rc::new(|x| x + 1);
1437+
use_fn(dyn_dispatch);
1438+
}
1439+
1440+
fn use_fn_once<F: FnOnce(u8) -> u8>(fun: F) {
1441+
assert_eq!(2, fun(1));
1442+
}
1443+
1444+
fn use_fn_mut<F: FnMut(u8) -> u8>(mut fun: F) {
1445+
assert_eq!(2, fun(1));
1446+
assert_eq!(3, fun(2));
1447+
}
1448+
1449+
fn use_fn<F: Fn(u8) -> u8>(fun: F) {
1450+
assert_eq!(2, fun(1));
1451+
}
1452+
}
1453+
}
1454+
13911455
#[cfg(test)]
13921456
mod tests {
13931457
use super::{Rc, Weak};

0 commit comments

Comments
 (0)