From 53f1e6b7ef705467faeff60f85db613e82c9b224 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 4 May 2023 10:55:21 +1000 Subject: [PATCH] Use `Cow` in `{D,Subd}iagnosticMessage`. Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment: ``` // FIXME(davidtwco): can a `Cow<'static, str>` be used here? ``` This commit answers that question in the affirmative. It's not the most compelling change ever, but it might be worth merging. This requires changing the `impl<'a> From<&'a str>` impls to `impl From<&'static str>`, which involves a bunch of knock-on changes that require/result in call sites being a little more precise about exactly what kind of string they use to create errors, and not just `&str`. This will result in fewer unnecessary allocations, though this will not have any notable perf effects given that these are error paths. Note that I was lazy within Clippy, using `to_string` in a few places to preserve the existing string imprecision. I could have used `impl Into<{D,Subd}iagnosticMessage>` in various places as is done in the compiler, but that would have required changes to *many* call sites (mostly changing `&format("...")` to `format!("...")`) which didn't seem worthwhile. --- clippy_lints/src/missing_const_for_fn.rs | 2 +- clippy_lints/src/needless_pass_by_value.rs | 11 ++++------- clippy_lints/src/unnecessary_wraps.rs | 2 +- clippy_utils/src/diagnostics.rs | 22 ++++++++++++---------- clippy_utils/src/sugg.rs | 6 +++--- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index f1831a30461..3b7eccad79d 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -154,7 +154,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) { if cx.tcx.is_const_fn_raw(def_id.to_def_id()) { - cx.tcx.sess.span_err(span, err.as_ref()); + cx.tcx.sess.span_err(span, err); } } else { span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`"); diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 0bb1775aae9..7d53fe65658 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -26,7 +26,6 @@ use rustc_span::{sym, Span}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; -use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -240,9 +239,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { snippet_opt(cx, span) .map_or( "change the call to".into(), - |x| Cow::from(format!("change `{x}` to")), - ) - .as_ref(), + |x| format!("change `{x}` to"), + ), suggestion, Applicability::Unspecified, ); @@ -270,9 +268,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { snippet_opt(cx, span) .map_or( "change the call to".into(), - |x| Cow::from(format!("change `{x}` to")) - ) - .as_ref(), + |x| format!("change `{x}` to") + ), suggestion, Applicability::Unspecified, ); diff --git a/clippy_lints/src/unnecessary_wraps.rs b/clippy_lints/src/unnecessary_wraps.rs index 8b0e0ce5a30..5073eb02bd8 100644 --- a/clippy_lints/src/unnecessary_wraps.rs +++ b/clippy_lints/src/unnecessary_wraps.rs @@ -163,7 +163,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps { span_lint_and_then(cx, UNNECESSARY_WRAPS, span, lint_msg.as_str(), |diag| { diag.span_suggestion( fn_decl.output.span(), - return_type_sugg_msg.as_str(), + return_type_sugg_msg, return_type_sugg, Applicability::MaybeIncorrect, ); diff --git a/clippy_utils/src/diagnostics.rs b/clippy_utils/src/diagnostics.rs index 812f6fe71a0..edd87546a5f 100644 --- a/clippy_utils/src/diagnostics.rs +++ b/clippy_utils/src/diagnostics.rs @@ -46,7 +46,7 @@ fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { /// | ^^^^^^^^^^^^^^^^^^^^^^^ /// ``` pub fn span_lint(cx: &T, lint: &'static Lint, sp: impl Into, msg: &str) { - cx.struct_span_lint(lint, sp, msg, |diag| { + cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { docs_link(diag, lint); diag }); @@ -80,11 +80,12 @@ pub fn span_lint_and_help( help_span: Option, help: &str, ) { - cx.struct_span_lint(lint, span, msg, |diag| { + cx.struct_span_lint(lint, span, msg.to_string(), |diag| { + let help = help.to_string(); if let Some(help_span) = help_span { - diag.span_help(help_span, help); + diag.span_help(help_span, help.to_string()); } else { - diag.help(help); + diag.help(help.to_string()); } docs_link(diag, lint); diag @@ -122,7 +123,8 @@ pub fn span_lint_and_note( note_span: Option, note: &str, ) { - cx.struct_span_lint(lint, span, msg, |diag| { + cx.struct_span_lint(lint, span, msg.to_string(), |diag| { + let note = note.to_string(); if let Some(note_span) = note_span { diag.span_note(note_span, note); } else { @@ -143,7 +145,7 @@ where S: Into, F: FnOnce(&mut Diagnostic), { - cx.struct_span_lint(lint, sp, msg, |diag| { + cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); diag @@ -151,7 +153,7 @@ where } pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| { + cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { docs_link(diag, lint); diag }); @@ -165,7 +167,7 @@ pub fn span_lint_hir_and_then( msg: &str, f: impl FnOnce(&mut Diagnostic), ) { - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| { + cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); diag @@ -202,7 +204,7 @@ pub fn span_lint_and_sugg( applicability: Applicability, ) { span_lint_and_then(cx, lint, sp, msg, |diag| { - diag.span_suggestion(sp, help, sugg, applicability); + diag.span_suggestion(sp, help.to_string(), sugg, applicability); }); } @@ -232,5 +234,5 @@ pub fn multispan_sugg_with_applicability( ) where I: IntoIterator, { - diag.multipart_suggestion(help_msg, sugg.into_iter().collect(), applicability); + diag.multipart_suggestion(help_msg.to_string(), sugg.into_iter().collect(), applicability); } diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 14f7f03016f..f477524eec5 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -741,7 +741,7 @@ impl DiagnosticExt for rustc_errors::Diagnostic { if let Some(indent) = indentation(cx, item) { let span = item.with_hi(item.lo()); - self.span_suggestion(span, msg, format!("{attr}\n{indent}"), applicability); + self.span_suggestion(span, msg.to_string(), format!("{attr}\n{indent}"), applicability); } } @@ -762,7 +762,7 @@ impl DiagnosticExt for rustc_errors::Diagnostic { }) .collect::(); - self.span_suggestion(span, msg, format!("{new_item}\n{indent}"), applicability); + self.span_suggestion(span, msg.to_string(), format!("{new_item}\n{indent}"), applicability); } } @@ -779,7 +779,7 @@ impl DiagnosticExt for rustc_errors::Diagnostic { } } - self.span_suggestion(remove_span, msg, "", applicability); + self.span_suggestion(remove_span, msg.to_string(), "", applicability); } }