@@ -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;
@@ -1346,49 +1345,88 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
1346
1345
}
1347
1346
}
1348
1347
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
+
1349
1393
impl < ' tcx > Predicate < ' tcx > {
1350
1394
/// Iterates over the types in this predicate. Note that in all
1351
1395
/// cases this is skipping over a binder, so late-bound regions
1352
1396
/// 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 {
1355
1399
ty:: Predicate :: Trait ( ref data) => {
1356
- data. skip_binder ( ) . input_types ( ) . collect ( )
1400
+ WalkTysIter :: InputTypes ( data. skip_binder ( ) . input_types ( ) )
1357
1401
}
1358
1402
ty:: Predicate :: Subtype ( binder) => {
1359
1403
let SubtypePredicate { a, b, a_is_expected : _ } = binder. skip_binder ( ) ;
1360
- vec ! [ a, b]
1404
+ WalkTysIter :: Two ( a, b)
1361
1405
}
1362
1406
ty:: Predicate :: TypeOutlives ( binder) => {
1363
- vec ! [ binder. skip_binder( ) . 0 ]
1407
+ WalkTysIter :: One ( binder. skip_binder ( ) . 0 )
1364
1408
}
1365
1409
ty:: Predicate :: RegionOutlives ( ..) => {
1366
- vec ! [ ]
1410
+ WalkTysIter :: None
1367
1411
}
1368
1412
ty:: Predicate :: Projection ( ref data) => {
1369
1413
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 ) ) )
1371
1416
}
1372
1417
ty:: Predicate :: WellFormed ( data) => {
1373
- vec ! [ data]
1418
+ WalkTysIter :: One ( data)
1374
1419
}
1375
1420
ty:: Predicate :: ObjectSafe ( _trait_def_id) => {
1376
- vec ! [ ]
1421
+ WalkTysIter :: None
1377
1422
}
1378
1423
ty:: Predicate :: ClosureKind ( _closure_def_id, closure_substs, _kind) => {
1379
- closure_substs. substs . types ( ) . collect ( )
1424
+ WalkTysIter :: Types ( closure_substs. substs . types ( ) )
1380
1425
}
1381
1426
ty:: Predicate :: ConstEvaluatable ( _, substs) => {
1382
- substs. types ( ) . collect ( )
1427
+ WalkTysIter :: Types ( substs. types ( ) )
1383
1428
}
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
+ }
1392
1430
}
1393
1431
1394
1432
pub fn to_opt_poly_trait_ref ( & self ) -> Option < PolyTraitRef < ' tcx > > {
0 commit comments