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