@@ -1140,43 +1140,51 @@ fn detect_same_item_push<'tcx>(
1140
1140
walk_expr ( & mut same_item_push_visitor, body) ;
1141
1141
if same_item_push_visitor. should_lint {
1142
1142
if let Some ( ( vec, pushed_item) ) = same_item_push_visitor. vec_push {
1143
- // Make sure that the push does not involve possibly mutating values
1144
- if let PatKind :: Wild = pat. kind {
1145
- let vec_str = snippet_with_macro_callsite ( cx, vec. span , "" ) ;
1146
- let item_str = snippet_with_macro_callsite ( cx, pushed_item. span , "" ) ;
1147
- if let ExprKind :: Path ( ref qpath) = pushed_item. kind {
1148
- if_chain ! {
1149
- if let Res :: Local ( hir_id) = qpath_res( cx, qpath, pushed_item. hir_id) ;
1150
- let node = cx. tcx. hir( ) . get( hir_id) ;
1151
- if let Node :: Binding ( pat) = node;
1152
- if let PatKind :: Binding ( bind_ann, ..) = pat. kind;
1153
- if !matches!( bind_ann, BindingAnnotation :: RefMut | BindingAnnotation :: Mutable ) ;
1154
- then {
1155
- span_lint_and_help(
1156
- cx,
1157
- SAME_ITEM_PUSH ,
1158
- vec. span,
1159
- "it looks like the same item is being pushed into this Vec" ,
1160
- None ,
1161
- & format!(
1162
- "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})" ,
1163
- item_str, vec_str, item_str
1164
- ) ,
1165
- )
1143
+ let ty = cx. typeck_results ( ) . expr_ty ( pushed_item) ;
1144
+ if cx
1145
+ . tcx
1146
+ . lang_items ( )
1147
+ . clone_trait ( )
1148
+ . map_or ( false , |id| implements_trait ( cx, ty, id, & [ ] ) )
1149
+ {
1150
+ // Make sure that the push does not involve possibly mutating values
1151
+ if let PatKind :: Wild = pat. kind {
1152
+ let vec_str = snippet_with_macro_callsite ( cx, vec. span , "" ) ;
1153
+ let item_str = snippet_with_macro_callsite ( cx, pushed_item. span , "" ) ;
1154
+ if let ExprKind :: Path ( ref qpath) = pushed_item. kind {
1155
+ if_chain ! {
1156
+ if let Res :: Local ( hir_id) = qpath_res( cx, qpath, pushed_item. hir_id) ;
1157
+ let node = cx. tcx. hir( ) . get( hir_id) ;
1158
+ if let Node :: Binding ( pat) = node;
1159
+ if let PatKind :: Binding ( bind_ann, ..) = pat. kind;
1160
+ if !matches!( bind_ann, BindingAnnotation :: RefMut | BindingAnnotation :: Mutable ) ;
1161
+ then {
1162
+ span_lint_and_help(
1163
+ cx,
1164
+ SAME_ITEM_PUSH ,
1165
+ vec. span,
1166
+ "it looks like the same item is being pushed into this Vec" ,
1167
+ None ,
1168
+ & format!(
1169
+ "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})" ,
1170
+ item_str, vec_str, item_str
1171
+ ) ,
1172
+ )
1173
+ }
1166
1174
}
1175
+ } else if mutated_variables ( pushed_item, cx) . map_or ( false , |mutvars| mutvars. is_empty ( ) ) {
1176
+ span_lint_and_help (
1177
+ cx,
1178
+ SAME_ITEM_PUSH ,
1179
+ vec. span ,
1180
+ "it looks like the same item is being pushed into this Vec" ,
1181
+ None ,
1182
+ & format ! (
1183
+ "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})" ,
1184
+ item_str, vec_str, item_str
1185
+ ) ,
1186
+ )
1167
1187
}
1168
- } else if mutated_variables ( pushed_item, cx) . map_or ( false , |mutvars| mutvars. is_empty ( ) ) {
1169
- span_lint_and_help (
1170
- cx,
1171
- SAME_ITEM_PUSH ,
1172
- vec. span ,
1173
- "it looks like the same item is being pushed into this Vec" ,
1174
- None ,
1175
- & format ! (
1176
- "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})" ,
1177
- item_str, vec_str, item_str
1178
- ) ,
1179
- )
1180
1188
}
1181
1189
}
1182
1190
}
0 commit comments