Skip to content

Commit 3452d9d

Browse files
authored
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`
2 parents f914b82 + 10739d4 commit 3452d9d

File tree

2 files changed

+40
-26
lines changed

2 files changed

+40
-26
lines changed

library/core/src/const_closure.rs

+39-25
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@ use crate::marker::Destruct;
1616
/// assert!(7 == cl(2));
1717
/// assert!(8 == cl(1));
1818
/// ```
19-
pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> {
20-
data: &'a mut CapturedData,
21-
func: Function,
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,
2225
}
23-
24-
impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> {
26+
impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> {
2527
/// Function for creating a new closure.
2628
///
2729
/// `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.
2831
///
2932
/// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
3033
/// and return the return value of the closure.
@@ -39,25 +42,36 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Fun
3942
}
4043
}
4144

42-
impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
43-
FnOnce<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
44-
where
45-
Function:
46-
~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
47-
{
48-
type Output = ClosureReturnValue;
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;
4954

50-
extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
51-
self.call_mut(args)
52-
}
53-
}
54-
55-
impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
56-
FnMut<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
57-
where
58-
Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
59-
{
60-
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
61-
(self.func)(self.data, args)
62-
}
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+
};
6372
}
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);

library/core/src/ops/try_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>::
379379
pub(crate) struct NeverShortCircuit<T>(pub T);
380380

381381
impl<T> NeverShortCircuit<T> {
382-
/// Wrap a binary `FnMut` to return its result wrapped in a `NeverShortCircuit`.
382+
/// Implementation for building `ConstFnMutClosure` for wrapping the output of a ~const FnMut in a `NeverShortCircuit`.
383383
#[inline]
384384
pub const fn wrap_mut_2_imp<A, B, F: ~const FnMut(A, B) -> T>(
385385
f: &mut F,

0 commit comments

Comments
 (0)