@@ -87,32 +87,44 @@ impl LateLintPass<'_> for AvoidableSliceIndexing {
87
87
}
88
88
89
89
fn find_slice_values ( cx : & LateContext < ' _ > , pat : & hir:: Pat < ' _ > ) -> Option < FxHashMap < hir:: HirId , SliceLintInformation > > {
90
- // TODO xFrednet 2021-08-31: Test with sub pattern stuff
91
-
90
+ let mut removed_pat: FxHashSet < Symbol > = FxHashSet :: default ( ) ;
92
91
let mut ident_to_id: FxHashMap < Symbol , hir:: HirId > = FxHashMap :: default ( ) ;
93
92
let mut slices: FxHashMap < hir:: HirId , SliceLintInformation > = FxHashMap :: default ( ) ;
94
- pat. each_binding ( |binding, hir_id, span, ident| {
95
- // We'll just ignore mut and ref mut for simplicity sake right now
96
- if let hir:: BindingAnnotation :: Mutable | hir:: BindingAnnotation :: RefMut = binding {
97
- return ;
98
- }
93
+ pat. walk_always ( |pat| {
94
+ if let hir:: PatKind :: Binding ( binding, _, ident, sub_pat) = pat. kind {
95
+ // We'll just ignore mut and ref mut for simplicity sake right now
96
+ if let hir:: BindingAnnotation :: Mutable | hir:: BindingAnnotation :: RefMut = binding {
97
+ return ;
98
+ }
99
+
100
+ // This block catches bindings with sub patterns. It would be hard to build a correct suggestion
101
+ // for them and it's likely that the user knows what they are doing in such a case.
102
+ if removed_pat. contains ( & ident. name ) {
103
+ return ;
104
+ }
105
+ if sub_pat. is_some ( ) {
106
+ removed_pat. insert ( ident. name ) ;
107
+ ident_to_id. remove ( & ident. name ) . map ( |key| slices. remove ( & key) ) ;
108
+ return ;
109
+ }
99
110
100
- let bound_ty = cx. typeck_results ( ) . node_type ( hir_id) ;
101
- if let ty:: Slice ( inner_ty) | ty:: Array ( inner_ty, _) = bound_ty. peel_refs ( ) . kind ( ) {
102
- // The values need to use the `ref` keyword if they can't be coppied.
103
- // This will need to be adjusted if the lint want to support multable access in the future
104
- let needs_ref = !bound_ty. is_ref ( )
105
- || !cx
106
- . tcx
107
- . lang_items ( )
108
- . copy_trait ( )
109
- . map_or ( false , |trait_id| implements_trait ( cx, inner_ty, trait_id, & [ ] ) ) ;
111
+ let bound_ty = cx. typeck_results ( ) . node_type ( pat . hir_id ) ;
112
+ if let ty:: Slice ( inner_ty) | ty:: Array ( inner_ty, _) = bound_ty. peel_refs ( ) . kind ( ) {
113
+ // The values need to use the `ref` keyword if they can't be coppied.
114
+ // This will need to be adjusted if the lint want to support multable access in the future
115
+ let needs_ref = !bound_ty. is_ref ( )
116
+ || !cx
117
+ . tcx
118
+ . lang_items ( )
119
+ . copy_trait ( )
120
+ . map_or ( false , |trait_id| implements_trait ( cx, inner_ty, trait_id, & [ ] ) ) ;
110
121
111
- let key = * ident_to_id. entry ( ident. name ) . or_insert ( hir_id) ;
112
- let slice_info = slices
113
- . entry ( key)
114
- . or_insert_with ( || SliceLintInformation :: new ( ident, needs_ref) ) ;
115
- slice_info. pattern_spans . push ( span) ;
122
+ let key = * ident_to_id. entry ( ident. name ) . or_insert ( pat. hir_id ) ;
123
+ let slice_info = slices
124
+ . entry ( key)
125
+ . or_insert_with ( || SliceLintInformation :: new ( ident, needs_ref) ) ;
126
+ slice_info. pattern_spans . push ( pat. span ) ;
127
+ }
116
128
}
117
129
} ) ;
118
130
0 commit comments