diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-09-30 19:06:04 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-30 19:06:04 +0200 |
| commit | 3452d9d593d901622e4be835cb6eba710387796e (patch) | |
| tree | 3683ef8ac87703db1d7098a78dc600c08798c10d | |
| parent | f914b82a754c6d85c0a909ab152f5b611defef73 (diff) | |
| parent | 10739d475e95b825a3b57a726da5266f7d50c9e7 (diff) | |
Rollup merge of #102276 - ink-feather-org:const_closure_ext, r=fee1-dead
Added more const_closure functionality Enables ConstFnMutClosure to use a tuple of mutable references instead of just a mutable reference to a tuple. Removes the new function, since it would barely be usable with this new code. r? `@fee1-dead`
| -rw-r--r-- | library/core/src/const_closure.rs | 64 | ||||
| -rw-r--r-- | library/core/src/ops/try_trait.rs | 2 |
2 files changed, 40 insertions, 26 deletions
diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index d2e80e8e7e5..9e9c02093be 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -16,15 +16,18 @@ use crate::marker::Destruct; /// assert!(7 == cl(2)); /// assert!(8 == cl(1)); /// ``` -pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> { - data: &'a mut CapturedData, - func: Function, +pub(crate) struct ConstFnMutClosure<CapturedData, Function> { + /// The Data captured by the Closure. + /// Must be either a (mutable) reference or a tuple of (mutable) references. + pub data: CapturedData, + /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn + pub func: Function, } - -impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> { +impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> { /// Function for creating a new closure. /// /// `data` is the a mutable borrow of data that is captured from the environment. + /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually. /// /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure /// and return the return value of the closure. @@ -39,25 +42,36 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Fun } } -impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const - FnOnce<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function> -where - Function: - ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct, -{ - type Output = ClosureReturnValue; +macro_rules! impl_fn_mut_tuple { + ($($var:ident)*) => { + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct, + { + type Output = ClosureReturnValue; - extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { - self.call_mut(args) - } -} - -impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const - FnMut<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function> -where - Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue, -{ - extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { - (self.func)(self.data, args) - } + extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { + self.call_mut(args) + } + } + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue, + { + extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { + #[allow(non_snake_case)] + let ($($var),*) = &mut self.data; + (self.func)(($($var),*), args) + } + } + }; } +impl_fn_mut_tuple!(A); +impl_fn_mut_tuple!(A B); +impl_fn_mut_tuple!(A B C); +impl_fn_mut_tuple!(A B C D); +impl_fn_mut_tuple!(A B C D E); diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index 33df9e6c5cd..84a69046807 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -379,7 +379,7 @@ pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>:: pub(crate) struct NeverShortCircuit<T>(pub T); impl<T> NeverShortCircuit<T> { - /// Wrap a binary `FnMut` to return its result wrapped in a `NeverShortCircuit`. + /// Implementation for building `ConstFnMutClosure` for wrapping the output of a ~const FnMut in a `NeverShortCircuit`. #[inline] pub const fn wrap_mut_2_imp<A, B, F: ~const FnMut(A, B) -> T>( f: &mut F, |
