@@ -2950,7 +2950,7 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
2950
2950
for ref stmt in block. stmts {
2951
2951
if_chain ! {
2952
2952
if let StmtKind :: Local (
2953
- Local { pat: Pat { kind: PatKind :: Binding ( _, _, ident, .. ) , .. } ,
2953
+ Local { pat: Pat { hir_id : pat_id , kind: PatKind :: Binding ( _, _, ident, .. ) , .. } ,
2954
2954
init: Some ( ref init_expr) , .. }
2955
2955
) = stmt. kind;
2956
2956
if let ExprKind :: MethodCall ( ref method_name, _, & [ ref iter_source] , ..) = init_expr. kind;
@@ -2964,6 +2964,16 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
2964
2964
if let Some ( iter_calls) = detect_iter_and_into_iters( block, * ident) ;
2965
2965
if iter_calls. len( ) == 1 ;
2966
2966
then {
2967
+ let mut used_count_visitor = UsedCountVisitor {
2968
+ cx,
2969
+ id: * pat_id,
2970
+ count: 0 ,
2971
+ } ;
2972
+ walk_block( & mut used_count_visitor, block) ;
2973
+ if used_count_visitor. count > 1 {
2974
+ return ;
2975
+ }
2976
+
2967
2977
// Suggest replacing iter_call with iter_replacement, and removing stmt
2968
2978
let iter_call = & iter_calls[ 0 ] ;
2969
2979
span_lint_and_then(
@@ -3087,6 +3097,28 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor {
3087
3097
}
3088
3098
}
3089
3099
3100
+ struct UsedCountVisitor < ' a , ' tcx > {
3101
+ cx : & ' a LateContext < ' tcx > ,
3102
+ id : HirId ,
3103
+ count : usize ,
3104
+ }
3105
+
3106
+ impl < ' a , ' tcx > Visitor < ' tcx > for UsedCountVisitor < ' a , ' tcx > {
3107
+ type Map = Map < ' tcx > ;
3108
+
3109
+ fn visit_expr ( & mut self , expr : & ' tcx Expr < ' _ > ) {
3110
+ if same_var ( self . cx , expr, self . id ) {
3111
+ self . count += 1 ;
3112
+ } else {
3113
+ walk_expr ( self , expr) ;
3114
+ }
3115
+ }
3116
+
3117
+ fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
3118
+ NestedVisitorMap :: OnlyBodies ( self . cx . tcx . hir ( ) )
3119
+ }
3120
+ }
3121
+
3090
3122
/// Detect the occurrences of calls to `iter` or `into_iter` for the
3091
3123
/// given identifier
3092
3124
fn detect_iter_and_into_iters < ' tcx > ( block : & ' tcx Block < ' tcx > , identifier : Ident ) -> Option < Vec < IterFunction > > {
0 commit comments