@@ -33,12 +33,12 @@ use crate::consts::{constant, Constant};
33
33
use crate :: utils:: eager_or_lazy:: is_lazyness_candidate;
34
34
use crate :: utils:: usage:: mutated_variables;
35
35
use crate :: utils:: {
36
- contains_return, contains_ty, derefs_to_slice , get_parent_expr, get_trait_def_id, has_iter_method, higher,
37
- implements_trait , in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment,
38
- match_def_path , match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args,
39
- path_to_local_id , paths , remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability,
40
- snippet_with_macro_callsite , span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs,
41
- sugg , walk_ptrs_ty_depth , SpanlessEq ,
36
+ contains_return, contains_ty, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait ,
37
+ in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path ,
38
+ match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id , paths ,
39
+ remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite ,
40
+ span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg , walk_ptrs_ty_depth ,
41
+ SpanlessEq ,
42
42
} ;
43
43
44
44
declare_clippy_lint ! {
@@ -2803,6 +2803,46 @@ fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[
2803
2803
}
2804
2804
}
2805
2805
2806
+ pub ( crate ) fn derefs_to_slice < ' tcx > (
2807
+ cx : & LateContext < ' tcx > ,
2808
+ expr : & ' tcx hir:: Expr < ' tcx > ,
2809
+ ty : Ty < ' tcx > ,
2810
+ ) -> Option < & ' tcx hir:: Expr < ' tcx > > {
2811
+ fn may_slice < ' a > ( cx : & LateContext < ' a > , ty : Ty < ' a > ) -> bool {
2812
+ match ty. kind ( ) {
2813
+ ty:: Slice ( _) => true ,
2814
+ ty:: Adt ( def, _) if def. is_box ( ) => may_slice ( cx, ty. boxed_ty ( ) ) ,
2815
+ ty:: Adt ( ..) => is_type_diagnostic_item ( cx, ty, sym:: vec_type) ,
2816
+ ty:: Array ( _, size) => size
2817
+ . try_eval_usize ( cx. tcx , cx. param_env )
2818
+ . map_or ( false , |size| size < 32 ) ,
2819
+ ty:: Ref ( _, inner, _) => may_slice ( cx, inner) ,
2820
+ _ => false ,
2821
+ }
2822
+ }
2823
+
2824
+ if let hir:: ExprKind :: MethodCall ( ref path, _, ref args, _) = expr. kind {
2825
+ if path. ident . name == sym:: iter && may_slice ( cx, cx. typeck_results ( ) . expr_ty ( & args[ 0 ] ) ) {
2826
+ Some ( & args[ 0 ] )
2827
+ } else {
2828
+ None
2829
+ }
2830
+ } else {
2831
+ match ty. kind ( ) {
2832
+ ty:: Slice ( _) => Some ( expr) ,
2833
+ ty:: Adt ( def, _) if def. is_box ( ) && may_slice ( cx, ty. boxed_ty ( ) ) => Some ( expr) ,
2834
+ ty:: Ref ( _, inner, _) => {
2835
+ if may_slice ( cx, inner) {
2836
+ Some ( expr)
2837
+ } else {
2838
+ None
2839
+ }
2840
+ } ,
2841
+ _ => None ,
2842
+ }
2843
+ }
2844
+ }
2845
+
2806
2846
/// lint use of `unwrap()` for `Option`s and `Result`s
2807
2847
fn lint_unwrap ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > , unwrap_args : & [ hir:: Expr < ' _ > ] ) {
2808
2848
let obj_ty = cx. typeck_results ( ) . expr_ty ( & unwrap_args[ 0 ] ) . peel_refs ( ) ;
0 commit comments