@@ -49,7 +49,6 @@ use std::hash::{Hash, Hasher};
49
49
use std:: ops:: Deref ;
50
50
use rustc_data_structures:: sync:: { self , Lrc , ParallelIterator , par_iter} ;
51
51
use std:: slice;
52
- use std:: vec:: IntoIter ;
53
52
use std:: { mem, ptr} ;
54
53
use syntax:: ast:: { self , DUMMY_NODE_ID , Name , Ident , NodeId } ;
55
54
use syntax:: attr;
@@ -1343,49 +1342,88 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
1343
1342
}
1344
1343
}
1345
1344
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
+
1346
1390
impl < ' tcx > Predicate < ' tcx > {
1347
1391
/// Iterates over the types in this predicate. Note that in all
1348
1392
/// cases this is skipping over a binder, so late-bound regions
1349
1393
/// 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 {
1352
1396
ty:: Predicate :: Trait ( ref data) => {
1353
- data. skip_binder ( ) . input_types ( ) . collect ( )
1397
+ WalkTysIter :: InputTypes ( data. skip_binder ( ) . input_types ( ) )
1354
1398
}
1355
1399
ty:: Predicate :: Subtype ( binder) => {
1356
1400
let SubtypePredicate { a, b, a_is_expected : _ } = binder. skip_binder ( ) ;
1357
- vec ! [ a, b]
1401
+ WalkTysIter :: Two ( a, b)
1358
1402
}
1359
1403
ty:: Predicate :: TypeOutlives ( binder) => {
1360
- vec ! [ binder. skip_binder( ) . 0 ]
1404
+ WalkTysIter :: One ( binder. skip_binder ( ) . 0 )
1361
1405
}
1362
1406
ty:: Predicate :: RegionOutlives ( ..) => {
1363
- vec ! [ ]
1407
+ WalkTysIter :: None
1364
1408
}
1365
1409
ty:: Predicate :: Projection ( ref data) => {
1366
1410
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 ) ) )
1368
1413
}
1369
1414
ty:: Predicate :: WellFormed ( data) => {
1370
- vec ! [ data]
1415
+ WalkTysIter :: One ( data)
1371
1416
}
1372
1417
ty:: Predicate :: ObjectSafe ( _trait_def_id) => {
1373
- vec ! [ ]
1418
+ WalkTysIter :: None
1374
1419
}
1375
1420
ty:: Predicate :: ClosureKind ( _closure_def_id, closure_substs, _kind) => {
1376
- closure_substs. substs . types ( ) . collect ( )
1421
+ WalkTysIter :: Types ( closure_substs. substs . types ( ) )
1377
1422
}
1378
1423
ty:: Predicate :: ConstEvaluatable ( _, substs) => {
1379
- substs. types ( ) . collect ( )
1424
+ WalkTysIter :: Types ( substs. types ( ) )
1380
1425
}
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
+ }
1389
1427
}
1390
1428
1391
1429
pub fn to_opt_poly_trait_ref ( & self ) -> Option < PolyTraitRef < ' tcx > > {
0 commit comments