| use clippy_utils::consts::{ConstEvalCtxt, Constant}; |
| use clippy_utils::diagnostics::span_lint_and_sugg; |
| use clippy_utils::res::MaybeDef; |
| use clippy_utils::source::snippet; |
| use rustc_errors::Applicability; |
| use rustc_hir::{Expr, LangItem}; |
| use rustc_lint::LateContext; |
| |
| use super::REPEAT_ONCE; |
| |
| pub(super) fn check<'tcx>( |
| cx: &LateContext<'tcx>, |
| expr: &'tcx Expr<'_>, |
| recv: &'tcx Expr<'_>, |
| repeat_arg: &'tcx Expr<'_>, |
| ) { |
| if ConstEvalCtxt::new(cx).eval_local(repeat_arg, expr.span.ctxt()) == Some(Constant::Int(1)) { |
| let ty = cx.typeck_results().expr_ty(recv).peel_refs(); |
| if ty.is_str() { |
| span_lint_and_sugg( |
| cx, |
| REPEAT_ONCE, |
| expr.span, |
| "calling `repeat(1)` on str", |
| "consider using `.to_string()` instead", |
| format!("{}.to_string()", snippet(cx, recv.span, r#""...""#)), |
| Applicability::MachineApplicable, |
| ); |
| } else if ty.builtin_index().is_some() { |
| span_lint_and_sugg( |
| cx, |
| REPEAT_ONCE, |
| expr.span, |
| "calling `repeat(1)` on slice", |
| "consider using `.to_vec()` instead", |
| format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)), |
| Applicability::MachineApplicable, |
| ); |
| } else if ty.is_lang_item(cx, LangItem::String) { |
| span_lint_and_sugg( |
| cx, |
| REPEAT_ONCE, |
| expr.span, |
| "calling `repeat(1)` on a string literal", |
| "consider using `.clone()` instead", |
| format!("{}.clone()", snippet(cx, recv.span, r#""...""#)), |
| Applicability::MachineApplicable, |
| ); |
| } |
| } |
| } |