X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=clippy_lints%2Fsrc%2Frepeat_once.rs;h=898c70ace66f35776c42c3b6a866022af81c7751;hb=0efafa4a6e2d96f55584fe77782c289199a560b1;hp=b39e9d5a78c2082539204566de0d6ca22fab9117;hpb=8af28840d2b493897a54eb9a21e155c09e38f10f;p=rust.git diff --git a/clippy_lints/src/repeat_once.rs b/clippy_lints/src/repeat_once.rs index b39e9d5a78c..898c70ace66 100644 --- a/clippy_lints/src/repeat_once.rs +++ b/clippy_lints/src/repeat_once.rs @@ -1,5 +1,4 @@ -use crate::consts::{constant_context, Constant}; -use crate::utils::in_macro; +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; @@ -11,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); @@ -33,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()` " @@ -43,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, @@ -69,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,