1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::source::snippet;
3 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
4 use if_chain::if_chain;
5 use rustc_errors::Applicability;
6 use rustc_hir::{Expr, ExprKind, LangItem};
7 use rustc_lint::LateContext;
10 use super::MATCH_ON_VEC_ITEMS;
12 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
14 if let Some(idx_expr) = is_vec_indexing(cx, scrutinee);
15 if let ExprKind::Index(vec, idx) = idx_expr.kind;
18 // FIXME: could be improved to suggest surrounding every pattern with Some(_),
19 // but only when `or_patterns` are stabilized.
24 "indexing into a vector may panic",
28 snippet(cx, vec.span, ".."),
29 snippet(cx, idx.span, "..")
31 Applicability::MaybeIncorrect
37 fn is_vec_indexing<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
39 if let ExprKind::Index(array, index) = expr.kind;
40 if is_vector(cx, array);
41 if !is_full_range(cx, index);
51 fn is_vector(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
52 let ty = cx.typeck_results().expr_ty(expr);
53 let ty = ty.peel_refs();
54 is_type_diagnostic_item(cx, ty, sym::Vec)
57 fn is_full_range(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
58 let ty = cx.typeck_results().expr_ty(expr);
59 let ty = ty.peel_refs();
60 is_type_lang_item(cx, ty, LangItem::RangeFull)