Skip to content

Commit 033cf98

Browse files
Support DoubleEndedIterator for subst_iter and subst_iter_copied
1 parent 34115d0 commit 033cf98

File tree

1 file changed

+69
-9
lines changed

1 file changed

+69
-9
lines changed

compiler/rustc_middle/src/ty/subst.rs

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
66
use crate::ty::visit::{TypeVisitable, TypeVisitor};
77
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
88

9-
use rustc_data_structures::captures::Captures;
109
use rustc_data_structures::intern::{Interned, WithStableHash};
1110
use rustc_hir::def_id::DefId;
1211
use rustc_macros::HashStable;
@@ -19,7 +18,7 @@ use std::fmt;
1918
use std::marker::PhantomData;
2019
use std::mem;
2120
use std::num::NonZeroUsize;
22-
use std::ops::ControlFlow;
21+
use std::ops::{ControlFlow, Deref};
2322
use std::slice;
2423

2524
/// An entity in the Rust type system, which can be one of
@@ -559,25 +558,86 @@ impl<T, U> EarlyBinder<(T, U)> {
559558
}
560559
}
561560

562-
impl<'tcx, 's, T: IntoIterator<Item = I>, I: TypeFoldable<'tcx>> EarlyBinder<T> {
561+
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
562+
where
563+
I::Item: TypeFoldable<'tcx>,
564+
{
563565
pub fn subst_iter(
564566
self,
565567
tcx: TyCtxt<'tcx>,
566568
substs: &'s [GenericArg<'tcx>],
567-
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> {
568-
self.0.into_iter().map(move |t| EarlyBinder(t).subst(tcx, substs))
569+
) -> SubstIter<'s, 'tcx, I> {
570+
SubstIter { it: self.0.into_iter(), tcx, substs }
571+
}
572+
}
573+
574+
pub struct SubstIter<'s, 'tcx, I: IntoIterator> {
575+
it: I::IntoIter,
576+
tcx: TyCtxt<'tcx>,
577+
substs: &'s [GenericArg<'tcx>],
578+
}
579+
580+
impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I>
581+
where
582+
I::Item: TypeFoldable<'tcx>,
583+
{
584+
type Item = I::Item;
585+
586+
fn next(&mut self) -> Option<Self::Item> {
587+
Some(EarlyBinder(self.it.next()?).subst(self.tcx, self.substs))
588+
}
589+
}
590+
591+
impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I>
592+
where
593+
I::IntoIter: DoubleEndedIterator,
594+
I::Item: TypeFoldable<'tcx>,
595+
{
596+
fn next_back(&mut self) -> Option<Self::Item> {
597+
Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs))
569598
}
570599
}
571600

572-
impl<'tcx, 's, 'a, T: IntoIterator<Item = &'a I>, I: Copy + TypeFoldable<'tcx> + 'a>
573-
EarlyBinder<T>
601+
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
602+
where
603+
I::Item: Deref,
604+
<I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
574605
{
575606
pub fn subst_iter_copied(
576607
self,
577608
tcx: TyCtxt<'tcx>,
578609
substs: &'s [GenericArg<'tcx>],
579-
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> + Captures<'a> {
580-
self.0.into_iter().map(move |t| EarlyBinder(*t).subst(tcx, substs))
610+
) -> SubstIterCopied<'s, 'tcx, I> {
611+
SubstIterCopied { it: self.0.into_iter(), tcx, substs }
612+
}
613+
}
614+
615+
pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> {
616+
it: I::IntoIter,
617+
tcx: TyCtxt<'tcx>,
618+
substs: &'a [GenericArg<'tcx>],
619+
}
620+
621+
impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I>
622+
where
623+
I::Item: Deref,
624+
<I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
625+
{
626+
type Item = <I::Item as Deref>::Target;
627+
628+
fn next(&mut self) -> Option<Self::Item> {
629+
Some(EarlyBinder(*self.it.next()?).subst(self.tcx, self.substs))
630+
}
631+
}
632+
633+
impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I>
634+
where
635+
I::IntoIter: DoubleEndedIterator,
636+
I::Item: Deref,
637+
<I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
638+
{
639+
fn next_back(&mut self) -> Option<Self::Item> {
640+
Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs))
581641
}
582642
}
583643

0 commit comments

Comments
 (0)