@@ -49,7 +49,6 @@ use std::hash::{Hash, Hasher};
4949use std:: ops:: Deref ;
5050use rustc_data_structures:: sync:: { self , Lrc , ParallelIterator , par_iter} ;
5151use std:: slice;
52- use std:: vec:: IntoIter ;
5352use std:: { mem, ptr} ;
5453use syntax:: ast:: { self , DUMMY_NODE_ID , Name , Ident , NodeId } ;
5554use syntax:: attr;
@@ -1346,49 +1345,88 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
13461345 }
13471346}
13481347
1348+ // A custom iterator used by Predicate::walk_tys.
1349+ enum WalkTysIter < ' tcx , I , J , K >
1350+ where I : Iterator < Item = Ty < ' tcx > > ,
1351+ J : Iterator < Item = Ty < ' tcx > > ,
1352+ K : Iterator < Item = Ty < ' tcx > >
1353+ {
1354+ None ,
1355+ One ( Ty < ' tcx > ) ,
1356+ Two ( Ty < ' tcx > , Ty < ' tcx > ) ,
1357+ Types ( I ) ,
1358+ InputTypes ( J ) ,
1359+ ProjectionTypes ( K )
1360+ }
1361+
1362+ impl < ' tcx , I , J , K > Iterator for WalkTysIter < ' tcx , I , J , K >
1363+ where I : Iterator < Item = Ty < ' tcx > > ,
1364+ J : Iterator < Item = Ty < ' tcx > > ,
1365+ K : Iterator < Item = Ty < ' tcx > >
1366+ {
1367+ type Item = Ty < ' tcx > ;
1368+
1369+ fn next ( & mut self ) -> Option < Ty < ' tcx > > {
1370+ match * self {
1371+ WalkTysIter :: None => None ,
1372+ WalkTysIter :: One ( item) => {
1373+ * self = WalkTysIter :: None ;
1374+ Some ( item)
1375+ } ,
1376+ WalkTysIter :: Two ( item1, item2) => {
1377+ * self = WalkTysIter :: One ( item2) ;
1378+ Some ( item1)
1379+ } ,
1380+ WalkTysIter :: Types ( ref mut iter) => {
1381+ iter. next ( )
1382+ } ,
1383+ WalkTysIter :: InputTypes ( ref mut iter) => {
1384+ iter. next ( )
1385+ } ,
1386+ WalkTysIter :: ProjectionTypes ( ref mut iter) => {
1387+ iter. next ( )
1388+ }
1389+ }
1390+ }
1391+ }
1392+
13491393impl < ' tcx > Predicate < ' tcx > {
13501394 /// Iterates over the types in this predicate. Note that in all
13511395 /// cases this is skipping over a binder, so late-bound regions
13521396 /// with depth 0 are bound by the predicate.
1353- pub fn walk_tys ( & self ) -> IntoIter < Ty < ' tcx > > {
1354- let vec : Vec < _ > = match * self {
1397+ pub fn walk_tys ( & ' a self ) -> impl Iterator < Item = Ty < ' tcx > > + ' a {
1398+ match * self {
13551399 ty:: Predicate :: Trait ( ref data) => {
1356- data. skip_binder ( ) . input_types ( ) . collect ( )
1400+ WalkTysIter :: InputTypes ( data. skip_binder ( ) . input_types ( ) )
13571401 }
13581402 ty:: Predicate :: Subtype ( binder) => {
13591403 let SubtypePredicate { a, b, a_is_expected : _ } = binder. skip_binder ( ) ;
1360- vec ! [ a, b]
1404+ WalkTysIter :: Two ( a, b)
13611405 }
13621406 ty:: Predicate :: TypeOutlives ( binder) => {
1363- vec ! [ binder. skip_binder( ) . 0 ]
1407+ WalkTysIter :: One ( binder. skip_binder ( ) . 0 )
13641408 }
13651409 ty:: Predicate :: RegionOutlives ( ..) => {
1366- vec ! [ ]
1410+ WalkTysIter :: None
13671411 }
13681412 ty:: Predicate :: Projection ( ref data) => {
13691413 let inner = data. skip_binder ( ) ;
1370- inner. projection_ty . substs . types ( ) . chain ( Some ( inner. ty ) ) . collect ( )
1414+ WalkTysIter :: ProjectionTypes (
1415+ inner. projection_ty . substs . types ( ) . chain ( Some ( inner. ty ) ) )
13711416 }
13721417 ty:: Predicate :: WellFormed ( data) => {
1373- vec ! [ data]
1418+ WalkTysIter :: One ( data)
13741419 }
13751420 ty:: Predicate :: ObjectSafe ( _trait_def_id) => {
1376- vec ! [ ]
1421+ WalkTysIter :: None
13771422 }
13781423 ty:: Predicate :: ClosureKind ( _closure_def_id, closure_substs, _kind) => {
1379- closure_substs. substs . types ( ) . collect ( )
1424+ WalkTysIter :: Types ( closure_substs. substs . types ( ) )
13801425 }
13811426 ty:: Predicate :: ConstEvaluatable ( _, substs) => {
1382- substs. types ( ) . collect ( )
1427+ WalkTysIter :: Types ( substs. types ( ) )
13831428 }
1384- } ;
1385-
1386- // FIXME: The only reason to collect into a vector here is that I was
1387- // too lazy to make the full (somewhat complicated) iterator
1388- // type that would be needed here. But I wanted this fn to
1389- // return an iterator conceptually, rather than a `Vec`, so as
1390- // to be closer to `Ty::walk`.
1391- vec. into_iter ( )
1429+ }
13921430 }
13931431
13941432 pub fn to_opt_poly_trait_ref ( & self ) -> Option < PolyTraitRef < ' tcx > > {
0 commit comments