@@ -1140,43 +1140,52 @@ fn detect_same_item_push<'tcx>(
11401140 walk_expr ( & mut same_item_push_visitor, body) ;
11411141 if same_item_push_visitor. should_lint {
11421142 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+ }
11661175 }
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+ )
11671188 }
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- )
11801189 }
11811190 }
11821191 }
0 commit comments