1 #![feature(fn_traits, unboxed_closures)]
3 use std
::marker
::PhantomData
;
5 // An erroneous variant of `run-pass/unboxed_closures-infer-recursive-fn.rs`
6 // where we attempt to perform mutation in the recursive function. This fails to compile
7 // because it winds up requiring `FnMut` which enforces linearity.
9 struct YCombinator
<F
,A
,R
> {
11 marker
: PhantomData
<(A
,R
)>,
14 impl<F
,A
,R
> YCombinator
<F
,A
,R
> {
15 fn new(f
: F
) -> YCombinator
<F
,A
,R
> {
16 YCombinator { func: f, marker: PhantomData }
20 impl<A
,R
,F
: FnMut(&mut dyn FnMut(A
) -> R
, A
) -> R
> FnMut
<(A
,)> for YCombinator
<F
,A
,R
> {
21 extern "rust-call" fn call_mut(&mut self, (arg
,): (A
,)) -> R
{
22 (self.func
)(self, arg
)
23 //~^ ERROR cannot borrow `*self` as mutable more than once at a time
27 impl<A
,R
,F
: FnMut(&mut dyn FnMut(A
) -> R
, A
) -> R
> FnOnce
<(A
,)> for YCombinator
<F
,A
,R
> {
29 extern "rust-call" fn call_once(mut self, args
: (A
,)) -> R
{
36 let factorial
= |recur
: &mut dyn FnMut(u32) -> u32, arg
: u32| -> u32 {
38 if arg
== 0 {1}
else {arg * recur(arg-1)}
40 let mut factorial
: YCombinator
<_
,u32,u32> = YCombinator
::new(factorial
);
41 let mut r
= factorial(10);
42 assert_eq
!(3628800, r
);