@@ -1536,31 +1536,17 @@ fn check_for_loop_explicit_counter<'tcx>(
1536
1536
expr : & ' tcx Expr < ' _ > ,
1537
1537
) {
1538
1538
// Look for variables that are incremented once per loop iteration.
1539
- let mut visitor = IncrementVisitor {
1540
- cx,
1541
- states : FxHashMap :: default ( ) ,
1542
- depth : 0 ,
1543
- done : false ,
1544
- } ;
1539
+ let mut visitor = IncrementVisitor :: new ( cx) ;
1545
1540
walk_expr ( & mut visitor, body) ;
1546
1541
1547
1542
// For each candidate, check the parent block to see if
1548
1543
// it's initialized to zero at the start of the loop.
1549
1544
if let Some ( block) = get_enclosing_block ( & cx, expr. hir_id ) {
1550
- for ( id, _) in visitor. states . iter ( ) . filter ( |& ( _, v) | * v == VarState :: IncrOnce ) {
1551
- let mut visitor2 = InitializeVisitor {
1552
- cx,
1553
- end_expr : expr,
1554
- var_id : * id,
1555
- state : VarState :: IncrOnce ,
1556
- name : None ,
1557
- depth : 0 ,
1558
- past_loop : false ,
1559
- } ;
1545
+ for id in visitor. into_results ( ) {
1546
+ let mut visitor2 = InitializeVisitor :: new ( cx, expr, id) ;
1560
1547
walk_block ( & mut visitor2, block) ;
1561
1548
1562
- if visitor2. state == VarState :: Warn {
1563
- if let Some ( name) = visitor2. name {
1549
+ if let Some ( name) = visitor2. get_result ( ) {
1564
1550
let mut applicability = Applicability :: MachineApplicable ;
1565
1551
1566
1552
// for some reason this is the only way to get the `Span`
@@ -1585,7 +1571,6 @@ fn check_for_loop_explicit_counter<'tcx>(
1585
1571
) ,
1586
1572
applicability,
1587
1573
) ;
1588
- }
1589
1574
}
1590
1575
}
1591
1576
}
@@ -2142,6 +2127,24 @@ struct IncrementVisitor<'a, 'tcx> {
2142
2127
done : bool ,
2143
2128
}
2144
2129
2130
+ impl < ' a , ' tcx > IncrementVisitor < ' a , ' tcx > {
2131
+ fn new ( cx : & ' a LateContext < ' a , ' tcx > ) -> Self {
2132
+ Self {
2133
+ cx,
2134
+ states : FxHashMap :: default ( ) ,
2135
+ depth : 0 ,
2136
+ done : false ,
2137
+ }
2138
+ }
2139
+
2140
+ fn into_results ( self ) -> impl Iterator < Item = HirId > {
2141
+ self . states
2142
+ . into_iter ( )
2143
+ . filter ( |( _, state) | * state == VarState :: IncrOnce )
2144
+ . map ( |( id, _) | id)
2145
+ }
2146
+ }
2147
+
2145
2148
impl < ' a , ' tcx > Visitor < ' tcx > for IncrementVisitor < ' a , ' tcx > {
2146
2149
type Map = Map < ' tcx > ;
2147
2150
@@ -2209,6 +2212,28 @@ struct InitializeVisitor<'a, 'tcx> {
2209
2212
past_loop : bool ,
2210
2213
}
2211
2214
2215
+ impl < ' a , ' tcx > InitializeVisitor < ' a , ' tcx > {
2216
+ fn new ( cx : & ' a LateContext < ' a , ' tcx > , end_expr : & ' tcx Expr < ' tcx > , var_id : HirId ) -> Self {
2217
+ Self {
2218
+ cx,
2219
+ end_expr,
2220
+ var_id,
2221
+ state : VarState :: IncrOnce ,
2222
+ name : None ,
2223
+ depth : 0 ,
2224
+ past_loop : false ,
2225
+ }
2226
+ }
2227
+
2228
+ fn get_result ( & self ) -> Option < Name > {
2229
+ if self . state == VarState :: Warn {
2230
+ self . name
2231
+ } else {
2232
+ None
2233
+ }
2234
+ }
2235
+ }
2236
+
2212
2237
impl < ' a , ' tcx > Visitor < ' tcx > for InitializeVisitor < ' a , ' tcx > {
2213
2238
type Map = Map < ' tcx > ;
2214
2239
0 commit comments