about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-09-30 19:06:04 +0200
committerGitHub <noreply@github.com>2022-09-30 19:06:04 +0200
commit3452d9d593d901622e4be835cb6eba710387796e (patch)
tree3683ef8ac87703db1d7098a78dc600c08798c10d
parentf914b82a754c6d85c0a909ab152f5b611defef73 (diff)
parent10739d475e95b825a3b57a726da5266f7d50c9e7 (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.rs64
-rw-r--r--library/core/src/ops/try_trait.rs2
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,