@@ -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;
@@ -1343,49 +1342,88 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
13431342 }
13441343}
13451344
1345+ // A custom iterator used by Predicate::walk_tys.
1346+ enum WalkTysIter < ' tcx , I , J , K >
1347+ where I : Iterator < Item = Ty < ' tcx > > ,
1348+ J : Iterator < Item = Ty < ' tcx > > ,
1349+ K : Iterator < Item = Ty < ' tcx > >
1350+ {
1351+ None ,
1352+ One ( Ty < ' tcx > ) ,
1353+ Two ( Ty < ' tcx > , Ty < ' tcx > ) ,
1354+ Types ( I ) ,
1355+ InputTypes ( J ) ,
1356+ ProjectionTypes ( K )
1357+ }
1358+
1359+ impl < ' tcx , I , J , K > Iterator for WalkTysIter < ' tcx , I , J , K >
1360+ where I : Iterator < Item = Ty < ' tcx > > ,
1361+ J : Iterator < Item = Ty < ' tcx > > ,
1362+ K : Iterator < Item = Ty < ' tcx > >
1363+ {
1364+ type Item = Ty < ' tcx > ;
1365+
1366+ fn next ( & mut self ) -> Option < Ty < ' tcx > > {
1367+ match * self {
1368+ WalkTysIter :: None => None ,
1369+ WalkTysIter :: One ( item) => {
1370+ * self = WalkTysIter :: None ;
1371+ Some ( item)
1372+ } ,
1373+ WalkTysIter :: Two ( item1, item2) => {
1374+ * self = WalkTysIter :: One ( item2) ;
1375+ Some ( item1)
1376+ } ,
1377+ WalkTysIter :: Types ( ref mut iter) => {
1378+ iter. next ( )
1379+ } ,
1380+ WalkTysIter :: InputTypes ( ref mut iter) => {
1381+ iter. next ( )
1382+ } ,
1383+ WalkTysIter :: ProjectionTypes ( ref mut iter) => {
1384+ iter. next ( )
1385+ }
1386+ }
1387+ }
1388+ }
1389+
13461390impl < ' tcx > Predicate < ' tcx > {
13471391 /// Iterates over the types in this predicate. Note that in all
13481392 /// cases this is skipping over a binder, so late-bound regions
13491393 /// with depth 0 are bound by the predicate.
1350- pub fn walk_tys ( & self ) -> IntoIter < Ty < ' tcx > > {
1351- let vec : Vec < _ > = match * self {
1394+ pub fn walk_tys ( & ' a self ) -> impl Iterator < Item = Ty < ' tcx > > + ' a {
1395+ match * self {
13521396 ty:: Predicate :: Trait ( ref data) => {
1353- data. skip_binder ( ) . input_types ( ) . collect ( )
1397+ WalkTysIter :: InputTypes ( data. skip_binder ( ) . input_types ( ) )
13541398 }
13551399 ty:: Predicate :: Subtype ( binder) => {
13561400 let SubtypePredicate { a, b, a_is_expected : _ } = binder. skip_binder ( ) ;
1357- vec ! [ a, b]
1401+ WalkTysIter :: Two ( a, b)
13581402 }
13591403 ty:: Predicate :: TypeOutlives ( binder) => {
1360- vec ! [ binder. skip_binder( ) . 0 ]
1404+ WalkTysIter :: One ( binder. skip_binder ( ) . 0 )
13611405 }
13621406 ty:: Predicate :: RegionOutlives ( ..) => {
1363- vec ! [ ]
1407+ WalkTysIter :: None
13641408 }
13651409 ty:: Predicate :: Projection ( ref data) => {
13661410 let inner = data. skip_binder ( ) ;
1367- inner. projection_ty . substs . types ( ) . chain ( Some ( inner. ty ) ) . collect ( )
1411+ WalkTysIter :: ProjectionTypes (
1412+ inner. projection_ty . substs . types ( ) . chain ( Some ( inner. ty ) ) )
13681413 }
13691414 ty:: Predicate :: WellFormed ( data) => {
1370- vec ! [ data]
1415+ WalkTysIter :: One ( data)
13711416 }
13721417 ty:: Predicate :: ObjectSafe ( _trait_def_id) => {
1373- vec ! [ ]
1418+ WalkTysIter :: None
13741419 }
13751420 ty:: Predicate :: ClosureKind ( _closure_def_id, closure_substs, _kind) => {
1376- closure_substs. substs . types ( ) . collect ( )
1421+ WalkTysIter :: Types ( closure_substs. substs . types ( ) )
13771422 }
13781423 ty:: Predicate :: ConstEvaluatable ( _, substs) => {
1379- substs. types ( ) . collect ( )
1424+ WalkTysIter :: Types ( substs. types ( ) )
13801425 }
1381- } ;
1382-
1383- // FIXME: The only reason to collect into a vector here is that I was
1384- // too lazy to make the full (somewhat complicated) iterator
1385- // type that would be needed here. But I wanted this fn to
1386- // return an iterator conceptually, rather than a `Vec`, so as
1387- // to be closer to `Ty::walk`.
1388- vec. into_iter ( )
1426+ }
13891427 }
13901428
13911429 pub fn to_opt_poly_trait_ref ( & self ) -> Option < PolyTraitRef < ' tcx > > {
0 commit comments