Replace ConstFnMutClosure with const closures

This commit is contained in:
Deadbeef 2023-02-01 05:56:04 +00:00
parent 679dde7338
commit b886a4de15
7 changed files with 21 additions and 120 deletions

View File

@ -22,7 +22,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::const_closure::ConstFnMutClosure;
use crate::marker::Destruct;
use self::Ordering::*;
@ -1291,17 +1290,7 @@ where
F: ~const Destruct,
K: ~const Destruct,
{
const fn imp<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(
f: &mut F,
(v1, v2): (&T, &T),
) -> Ordering
where
T: ~const Destruct,
K: ~const Destruct,
{
f(v1).cmp(&f(v2))
}
max_by(v1, v2, ConstFnMutClosure::new(&mut f, imp))
max_by(v1, v2, const |v1, v2| f(v1).cmp(&f(v2)))
}
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types

View File

@ -1,78 +0,0 @@
use crate::marker::Destruct;
use crate::marker::Tuple;
/// Struct representing a closure with mutably borrowed data.
///
/// Example:
/// ```no_build
/// #![feature(const_mut_refs)]
/// use crate::const_closure::ConstFnMutClosure;
/// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 {
/// *state += arg;
/// *state
/// }
/// let mut i = 5;
/// let mut cl = ConstFnMutClosure::new(&mut i, imp);
///
/// assert!(7 == cl(2));
/// assert!(8 == cl(1));
/// ```
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 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.
pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
data: &'a mut CapturedData,
func: Function,
) -> Self
where
Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
{
Self { data, func }
}
}
macro_rules! impl_fn_mut_tuple {
($($var:ident)*) => {
#[allow(unused_parens)]
impl<'a, $($var,)* ClosureArguments: Tuple, 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)
}
}
#[allow(unused_parens)]
impl<'a, $($var,)* ClosureArguments: Tuple, 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);

View File

@ -1,5 +1,4 @@
use crate::array;
use crate::const_closure::ConstFnMutClosure;
use crate::iter::{ByRefSized, FusedIterator, Iterator, TrustedRandomAccessNoCoerce};
use crate::mem::{self, MaybeUninit};
use crate::ops::{ControlFlow, NeverShortCircuit, Try};
@ -189,13 +188,12 @@ where
I: Iterator,
{
#[inline]
default fn fold<B, F>(mut self, init: B, mut f: F) -> B
default fn fold<B, F>(mut self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
let fold = ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp);
self.try_fold(init, fold).0
self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0
}
}

View File

@ -1,7 +1,4 @@
use crate::{
const_closure::ConstFnMutClosure,
ops::{NeverShortCircuit, Try},
};
use crate::ops::{NeverShortCircuit, Try};
/// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics.
///
@ -39,13 +36,12 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
// `fold` needs ownership, so this can't forward directly.
I::try_fold(self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp))
.0
I::try_fold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0
}
#[inline]
@ -76,17 +72,12 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
}
#[inline]
fn rfold<B, F>(self, init: B, mut f: F) -> B
fn rfold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
// `rfold` needs ownership, so this can't forward directly.
I::try_rfold(
self.0,
init,
ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp),
)
.0
I::try_rfold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0
}
#[inline]

View File

@ -362,15 +362,13 @@ macro_rules! impl_fold_via_try_fold {
};
(@internal $fold:ident -> $try_fold:ident) => {
#[inline]
fn $fold<AAA, FFF>(mut self, init: AAA, mut fold: FFF) -> AAA
fn $fold<AAA, FFF>(mut self, init: AAA, fold: FFF) -> AAA
where
FFF: FnMut(AAA, Self::Item) -> AAA,
{
use crate::const_closure::ConstFnMutClosure;
use crate::ops::NeverShortCircuit;
let fold = ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp);
self.$try_fold(init, fold).0
self.$try_fold(init, NeverShortCircuit::wrap_mut_2(fold)).0
}
};
}

View File

@ -376,8 +376,6 @@ mod bool;
mod tuple;
mod unit;
mod const_closure;
#[stable(feature = "core_primitive", since = "1.43.0")]
pub mod primitive;

View File

@ -379,13 +379,18 @@ pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>::
pub(crate) struct NeverShortCircuit<T>(pub T);
impl<T> NeverShortCircuit<T> {
/// 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,
(a, b): (A, B),
) -> NeverShortCircuit<T> {
NeverShortCircuit(f(a, b))
pub fn wrap_mut_2<A, B>(
mut f: impl ~const FnMut(A, B) -> T,
) -> impl ~const FnMut(A, B) -> Self {
cfg_if! {
if #[cfg(bootstrap)] {
#[allow(unused_parens)]
(const move |a, b| NeverShortCircuit(f(a, b)))
} else {
const move |a, b| NeverShortCircuit(f(a, b))
}
}
}
}