]> git.lizzy.rs Git - rust.git/blob - library/core/src/const_closure.rs
Rollup merge of #102613 - TaKO8Ki:fix-part-of-101739, r=compiler-errors
[rust.git] / library / core / src / const_closure.rs
1 use crate::marker::Destruct;
2
3 /// Struct representing a closure with mutably borrowed data.
4 ///
5 /// Example:
6 /// ```no_build
7 /// #![feature(const_mut_refs)]
8 /// use crate::const_closure::ConstFnMutClosure;
9 /// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 {
10 ///   *state += arg;
11 ///   *state
12 /// }
13 /// let mut i = 5;
14 /// let mut cl = ConstFnMutClosure::new(&mut i, imp);
15 ///
16 /// assert!(7 == cl(2));
17 /// assert!(8 == cl(1));
18 /// ```
19 pub(crate) struct ConstFnMutClosure<CapturedData, Function> {
20     /// The Data captured by the Closure.
21     /// Must be either a (mutable) reference or a tuple of (mutable) references.
22     pub data: CapturedData,
23     /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn
24     pub func: Function,
25 }
26 impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> {
27     /// Function for creating a new closure.
28     ///
29     /// `data` is the a mutable borrow of data that is captured from the environment.
30     /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually.
31     ///
32     /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
33     ///   and return the return value of the closure.
34     pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
35         data: &'a mut CapturedData,
36         func: Function,
37     ) -> Self
38     where
39         Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
40     {
41         Self { data, func }
42     }
43 }
44
45 macro_rules! impl_fn_mut_tuple {
46     ($($var:ident)*) => {
47         #[allow(unused_parens)]
48         impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
49             FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
50         where
51             Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct,
52         {
53             type Output = ClosureReturnValue;
54
55             extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
56             self.call_mut(args)
57             }
58         }
59         #[allow(unused_parens)]
60         impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
61             FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
62         where
63             Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
64         {
65             extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
66                 #[allow(non_snake_case)]
67                 let ($($var),*) = &mut self.data;
68                 (self.func)(($($var),*), args)
69             }
70         }
71     };
72 }
73 impl_fn_mut_tuple!(A);
74 impl_fn_mut_tuple!(A B);
75 impl_fn_mut_tuple!(A B C);
76 impl_fn_mut_tuple!(A B C D);
77 impl_fn_mut_tuple!(A B C D E);