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