X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Frepeat_once.rs;h=898c70ace66f35776c42c3b6a866022af81c7751;hb=0efafa4a6e2d96f55584fe77782c289199a560b1;hp=d34e744eb944cd0631f0bc00b6d55ffdc6b6585c;hpb=d212c382c3d00b8a2bb701313c7bdd605ea7e128;p=rust.git diff --git a/clippy_lints/src/repeat_once.rs b/clippy_lints/src/repeat_once.rs index d34e744eb94..898c70ace66 100644 --- a/clippy_lints/src/repeat_once.rs +++ b/clippy_lints/src/repeat_once.rs @@ -1,5 +1,7 @@ -use crate::consts::{constant_context, Constant}; -use crate::utils::{in_macro, is_type_diagnostic_item, snippet, span_lint_and_sugg}; +use clippy_utils::consts::{constant_context, Constant}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet; +use clippy_utils::ty::is_type_diagnostic_item; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; @@ -8,17 +10,20 @@ use rustc_span::sym; declare_clippy_lint! { - /// **What it does:** Checks for usage of `.repeat(1)` and suggest the following method for each types. + /// ### What it does + /// Checks for usage of `.repeat(1)` and suggest the following method for each types. /// - `.to_string()` for `str` /// - `.clone()` for `String` /// - `.to_vec()` for `slice` /// - /// **Why is this bad?** For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning the string is the intention behind this, `clone()` should be used. + /// The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if + /// they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306)) /// - /// **Known problems:** None. - /// - /// **Example:** + /// ### Why is this bad? + /// For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning + /// the string is the intention behind this, `clone()` should be used. /// + /// ### Example /// ```rust /// fn main() { /// let x = String::from("hello world").repeat(1); @@ -30,6 +35,7 @@ /// let x = String::from("hello world").clone(); /// } /// ``` + #[clippy::version = "1.47.0"] pub REPEAT_ONCE, complexity, "using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` " @@ -40,12 +46,12 @@ impl<'tcx> LateLintPass<'tcx> for RepeatOnce { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'_>) { if_chain! { - if let ExprKind::MethodCall(path, _, [receiver, count], _) = &expr.kind; + if let ExprKind::MethodCall(path, [receiver, count], _) = &expr.kind; if path.ident.name == sym!(repeat); - if let Some(Constant::Int(1)) = constant_context(cx, cx.typeck_results()).expr(&count); - if !in_macro(receiver.span); + if constant_context(cx, cx.typeck_results()).expr(count) == Some(Constant::Int(1)); + if !receiver.span.from_expansion(); then { - let ty = cx.typeck_results().expr_ty(&receiver).peel_refs(); + let ty = cx.typeck_results().expr_ty(receiver).peel_refs(); if ty.is_str() { span_lint_and_sugg( cx, @@ -66,7 +72,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'_>) { format!("{}.to_vec()", snippet(cx, receiver.span, r#""...""#)), Applicability::MachineApplicable, ); - } else if is_type_diagnostic_item(cx, ty, sym::string_type) { + } else if is_type_diagnostic_item(cx, ty, sym::String) { span_lint_and_sugg( cx, REPEAT_ONCE,