1
Fork 0

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.
This commit is contained in:
Nicholas Nethercote 2023-05-04 10:55:21 +10:00
parent 1c53407e8c
commit 781111ef35
45 changed files with 308 additions and 287 deletions

View file

@ -2540,7 +2540,7 @@ fn show_candidates(
err.note(msg);
}
if let Some(note) = (*note).as_deref() {
err.note(note);
err.note(note.to_string());
}
} else {
let (_, descr_first, _, _) = &inaccessible_path_strings[0];

View file

@ -29,6 +29,7 @@ use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use std::borrow::Cow;
use std::iter;
use std::ops::Deref;
@ -1248,7 +1249,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}),
) if followed_by_brace => {
if let Some(sp) = closing_brace {
err.span_label(span, fallback_label);
err.span_label(span, fallback_label.to_string());
err.multipart_suggestion(
"surround the struct literal with parentheses",
vec![
@ -1320,7 +1321,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
);
}
_ => {
err.span_label(span, fallback_label);
err.span_label(span, fallback_label.to_string());
}
}
};
@ -1333,7 +1334,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}))
| PathSource::Struct,
) => {
err.span_label(span, fallback_label);
err.span_label(span, fallback_label.to_string());
err.span_suggestion_verbose(
span.shrink_to_hi(),
"use `!` to invoke the macro",
@ -1345,7 +1346,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
}
}
(Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => {
err.span_label(span, fallback_label);
err.span_label(span, fallback_label.to_string());
}
(Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {
err.span_label(span, "type aliases cannot be used as traits");
@ -1513,7 +1514,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
);
}
(Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }, _) if ns == ValueNS => {
err.span_label(span, fallback_label);
err.span_label(span, fallback_label.to_string());
err.note("can't use `Self` as a constructor, you must use the implemented struct");
}
(Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => {
@ -2243,7 +2244,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
&self,
err: &mut Diagnostic,
name: Option<&str>,
suggest: impl Fn(&mut Diagnostic, bool, Span, &str, String) -> bool,
suggest: impl Fn(&mut Diagnostic, bool, Span, Cow<'static, str>, String) -> bool,
) {
let mut suggest_note = true;
for rib in self.lifetime_ribs.iter().rev() {
@ -2288,22 +2289,23 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
(span, sugg)
};
if higher_ranked {
let message = format!(
let message = Cow::from(format!(
"consider making the {} lifetime-generic with a new `{}` lifetime",
kind.descr(),
name.unwrap_or("'a"),
);
should_continue = suggest(err, true, span, &message, sugg);
));
should_continue = suggest(err, true, span, message, sugg);
err.note_once(
"for more information on higher-ranked polymorphism, visit \
https://doc.rust-lang.org/nomicon/hrtb.html",
);
} else if let Some(name) = name {
let message = format!("consider introducing lifetime `{}` here", name);
should_continue = suggest(err, false, span, &message, sugg);
let message =
Cow::from(format!("consider introducing lifetime `{}` here", name));
should_continue = suggest(err, false, span, message, sugg);
} else {
let message = "consider introducing a named lifetime parameter";
should_continue = suggest(err, false, span, &message, sugg);
let message = Cow::from("consider introducing a named lifetime parameter");
should_continue = suggest(err, false, span, message, sugg);
}
}
LifetimeRibKind::Item => break,

View file

@ -827,7 +827,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if !is_allowed(feature) && !allowed_by_implication {
let lint_buffer = &mut self.lint_buffer;
let soft_handler =
|lint, span, msg: &_| lint_buffer.buffer_lint(lint, node_id, span, msg);
|lint, span, msg: String| lint_buffer.buffer_lint(lint, node_id, span, msg);
stability::report_unstable(
self.tcx.sess,
feature,
@ -846,7 +846,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let (message, lint) = stability::deprecation_message_and_lint(depr, "macro", &path);
stability::early_report_deprecation(
&mut self.lint_buffer,
&message,
message,
depr.suggestion,
lint,
span,