Skip to content

Use a GAT for Residual #104128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ where
pub fn try_from_fn<R, const N: usize, F>(cb: F) -> ChangeOutputType<R, [R::Output; N]>
where
F: FnMut(usize) -> R,
R: Try,
R::Residual: Residual<[R::Output; N]>,
R: Try<Residual: Residual>,
{
// SAFETY: we know for certain that this iterator will yield exactly `N`
// items.
Expand Down Expand Up @@ -535,11 +534,10 @@ impl<T, const N: usize> [T; N] {
/// assert_eq!(c, Some(a));
/// ```
#[unstable(feature = "array_try_map", issue = "79711")]
pub fn try_map<F, R>(self, f: F) -> ChangeOutputType<R, [R::Output; N]>
pub fn try_map<R, F>(self, f: F) -> ChangeOutputType<R, [R::Output; N]>
where
F: FnMut(T) -> R,
R: Try,
R::Residual: Residual<[R::Output; N]>,
R: Try<Residual: Residual>,
{
// SAFETY: we know for certain that this iterator will yield exactly `N`
// items.
Expand Down Expand Up @@ -809,15 +807,15 @@ impl<T, const N: usize> [T; N] {
///
/// It is up to the caller to guarantee that `iter` yields at least `N` items.
/// Violating this condition causes undefined behavior.
unsafe fn try_collect_into_array_unchecked<I, T, R, const N: usize>(iter: &mut I) -> R::TryType
unsafe fn try_collect_into_array_unchecked<I, T, const N: usize>(
iter: &mut I,
) -> ChangeOutputType<I::Item, [T; N]>
where
// Note: `TrustedLen` here is somewhat of an experiment. This is just an
// internal function, so feel free to remove if this bound turns out to be a
// bad idea. In that case, remember to also remove the lower bound
// `debug_assert!` below!
I: Iterator + TrustedLen,
I::Item: Try<Output = T, Residual = R>,
R: Residual<[T; N]>,
I: Iterator<Item: Try<Output = T, Residual: Residual>> + TrustedLen,
{
debug_assert!(N <= iter.size_hint().1.unwrap_or(usize::MAX));
debug_assert!(N <= iter.size_hint().0);
Expand Down Expand Up @@ -852,13 +850,11 @@ where
/// If `iter.next()` panicks, all items already yielded by the iterator are
/// dropped.
#[inline]
fn try_collect_into_array<I, T, R, const N: usize>(
fn try_collect_into_array<I, T, const N: usize>(
iter: &mut I,
) -> Result<R::TryType, IntoIter<T, N>>
) -> Result<ChangeOutputType<I::Item, [T; N]>, IntoIter<T, N>>
where
I: Iterator,
I::Item: Try<Output = T, Residual = R>,
R: Residual<[T; N]>,
I: Iterator<Item: Try<Output = T, Residual: Residual>>,
{
if N == 0 {
// SAFETY: An empty array is always inhabited and has no validity invariants.
Expand Down
7 changes: 3 additions & 4 deletions library/core/src/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,10 @@ pub(crate) struct GenericShunt<'a, I, R> {
/// Process the given iterator as if it yielded a the item's `Try::Output`
/// type instead. Any `Try::Residual`s encountered will stop the inner iterator
/// and be propagated back to the overall result.
pub(crate) fn try_process<I, T, R, F, U>(iter: I, mut f: F) -> ChangeOutputType<I::Item, U>
pub(crate) fn try_process<I, U, F>(iter: I, mut f: F) -> ChangeOutputType<I::Item, U>
where
I: Iterator<Item: Try<Output = T, Residual = R>>,
for<'a> F: FnMut(GenericShunt<'a, I, R>) -> U,
R: Residual<U>,
I: Iterator<Item: Try<Residual: Residual>>,
for<'a> F: FnMut(GenericShunt<'a, I, <I::Item as Try>::Residual>) -> U,
{
let mut residual = None;
let shunt = GenericShunt { iter, residual: &mut residual };
Expand Down
22 changes: 9 additions & 13 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1910,8 +1910,7 @@ pub trait Iterator {
fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
where
Self: Sized,
<Self as Iterator>::Item: Try,
<<Self as Iterator>::Item as Try>::Residual: Residual<B>,
Self::Item: Try<Residual: Residual>,
B: FromIterator<<Self::Item as Try>::Output>,
{
try_process(ByRefSized(self), |i| i.collect())
Expand Down Expand Up @@ -2512,12 +2511,11 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "iterator_try_reduce", reason = "new API", issue = "87053")]
fn try_reduce<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<R::Output>>
fn try_reduce<R, F>(&mut self, f: F) -> ChangeOutputType<R, Option<R::Output>>
where
Self: Sized,
F: FnMut(Self::Item, Self::Item) -> R,
R: Try<Output = Self::Item>,
R::Residual: Residual<Option<Self::Item>>,
R: Try<Output = Self::Item, Residual: Residual>,
{
let first = match self.next() {
Some(i) => i,
Expand Down Expand Up @@ -2769,20 +2767,18 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "try_find", reason = "new API", issue = "63178")]
fn try_find<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<Self::Item>>
fn try_find<R, F>(&mut self, f: F) -> ChangeOutputType<R, Option<Self::Item>>
where
Self: Sized,
F: FnMut(&Self::Item) -> R,
R: Try<Output = bool>,
R::Residual: Residual<Option<Self::Item>>,
R: Try<Output = bool, Residual: Residual>,
{
#[inline]
fn check<I, V, R>(
mut f: impl FnMut(&I) -> V,
) -> impl FnMut((), I) -> ControlFlow<R::TryType>
fn check<I, R>(
mut f: impl FnMut(&I) -> R,
) -> impl FnMut((), I) -> ControlFlow<ChangeOutputType<R, Option<I>>>
where
V: Try<Output = bool, Residual = R>,
R: Residual<Option<I>>,
R: Try<Output = bool, Residual: Residual>,
{
move |(), x| match f(&x).branch() {
ControlFlow::Continue(false) => ControlFlow::CONTINUE,
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/ops/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ impl<B, C> const ops::FromResidual for ControlFlow<B, C> {

#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<B, C> const ops::Residual<C> for ControlFlow<B, convert::Infallible> {
type TryType = ControlFlow<B, C>;
impl<B> const ops::Residual for ControlFlow<B, convert::Infallible> {
type TryType<C> = ControlFlow<B, C>;
}

impl<B, C> ControlFlow<B, C> {
Expand Down
11 changes: 6 additions & 5 deletions library/core/src/ops/try_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,15 @@ where
/// `<Result<Infallible, E> as Residual<T>>::TryType = Result<T, E>`.
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
#[const_trait]
pub trait Residual<O> {
pub trait Residual {
/// The "return" type of this meta-function.
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
type TryType: ~const Try<Output = O, Residual = Self>;
type TryType<O>: ~const Try<Output = O, Residual = Self>;
}

// This type alias is used in the return types of public functions, so rustc wants a stability attr
#[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")]
pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>::TryType;
pub(crate) type ChangeOutputType<T, O> = <<T as Try>::Residual as Residual>::TryType<O>;

/// An adapter for implementing non-try methods via the `Try` implementation.
///
Expand Down Expand Up @@ -413,8 +414,8 @@ impl<T> const FromResidual for NeverShortCircuit<T> {
}
}

impl<T> const Residual<T> for NeverShortCircuitResidual {
type TryType = NeverShortCircuit<T>;
impl const Residual for NeverShortCircuitResidual {
type TryType<T> = NeverShortCircuit<T>;
}

/// Implement `FromResidual<Yeet<T>>` on your type to enable
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2321,8 +2321,8 @@ impl<T> ops::FromResidual<ops::Yeet<()>> for Option<T> {

#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const ops::Residual<T> for Option<convert::Infallible> {
type TryType = Option<T>;
impl const ops::Residual for Option<convert::Infallible> {
type TryType<T> = Option<T>;
}

impl<T> Option<Option<T>> {
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,6 @@ impl<T, E, F: From<E>> ops::FromResidual<ops::Yeet<E>> for Result<T, F> {

#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T, E> const ops::Residual<T> for Result<convert::Infallible, E> {
type TryType = Result<T, E>;
impl<E> const ops::Residual for Result<convert::Infallible, E> {
type TryType<T> = Result<T, E>;
}