1
Fork 0

Restrict From<S> for {D,Subd}iagnosticMessage.

Currently a `{D,Subd}iagnosticMessage` can be created from any type that
impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static,
str>`, which are reasonable. It also includes `&String`, which is pretty
weird, and results in many places making unnecessary allocations for
patterns like this:
```
self.fatal(&format!(...))
```
This creates a string with `format!`, takes a reference, passes the
reference to `fatal`, which does an `into()`, which clones the
reference, doing a second allocation. Two allocations for a single
string, bleh.

This commit changes the `From` impls so that you can only create a
`{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static,
str>`. This requires changing all the places that currently create one
from a `&String`. Most of these are of the `&format!(...)` form
described above; each one removes an unnecessary static `&`, plus an
allocation when executed. There are also a few places where the existing
use of `&String` was more reasonable; these now just use `clone()` at
the call site.

As well as making the code nicer and more efficient, this is a step
towards possibly using `Cow<'static, str>` in
`{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing
the `From<&'a str>` impls to `From<&'static str>`, which is doable, but
I'm not yet sure if it's worthwhile.
This commit is contained in:
Nicholas Nethercote 2023-04-20 13:26:58 +10:00
parent a368898de7
commit 6b62f37402
177 changed files with 791 additions and 787 deletions

View file

@ -616,7 +616,7 @@ pub trait LintContext: Sized {
1 => ("an ", ""),
_ => ("", "s"),
};
db.span_label(span, &format!(
db.span_label(span, format!(
"this comment contains {}invisible unicode text flow control codepoint{}",
an,
s,
@ -680,12 +680,12 @@ pub trait LintContext: Sized {
);
}
BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
db.span_suggestion(span, note, sugg, Applicability::MaybeIncorrect);
}
BuiltinLintDiagnostics::UnusedImports(message, replaces, in_test_module) => {
if !replaces.is_empty() {
db.tool_only_multipart_suggestion(
&message,
message,
replaces,
Applicability::MachineApplicable,
);
@ -720,13 +720,13 @@ pub trait LintContext: Sized {
}
BuiltinLintDiagnostics::MissingAbi(span, default_abi) => {
db.span_label(span, "ABI should be specified here");
db.help(&format!("the default ABI is {}", default_abi.name()));
db.help(format!("the default ABI is {}", default_abi.name()));
}
BuiltinLintDiagnostics::LegacyDeriveHelpers(span) => {
db.span_label(span, "the attribute is introduced here");
}
BuiltinLintDiagnostics::ProcMacroBackCompat(note) => {
db.note(&note);
db.note(note);
}
BuiltinLintDiagnostics::OrPatternsBackCompat(span,suggestion) => {
db.span_suggestion(span, "use pat_param to preserve semantics", suggestion, Applicability::MachineApplicable);
@ -747,13 +747,13 @@ pub trait LintContext: Sized {
} => {
db.span_note(
invoc_span,
&format!("the built-in attribute `{attr_name}` will be ignored, since it's applied to the macro invocation `{macro_name}`")
format!("the built-in attribute `{attr_name}` will be ignored, since it's applied to the macro invocation `{macro_name}`")
);
}
BuiltinLintDiagnostics::TrailingMacro(is_trailing, name) => {
if is_trailing {
db.note("macro invocations at the end of a block are treated as expressions");
db.note(&format!("to ignore the value produced by the macro, add a semicolon after the invocation of `{name}`"));
db.note(format!("to ignore the value produced by the macro, add a semicolon after the invocation of `{name}`"));
}
}
BuiltinLintDiagnostics::BreakWithLabelAndLoop(span) => {
@ -765,7 +765,7 @@ pub trait LintContext: Sized {
);
}
BuiltinLintDiagnostics::NamedAsmLabel(help) => {
db.help(&help);
db.help(help);
db.note("see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information");
},
BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), None) => {
@ -793,7 +793,7 @@ pub trait LintContext: Sized {
possibilities.sort();
let possibilities = possibilities.join(", ");
db.note(&format!("expected values for `{name}` are: {possibilities}"));
db.note(format!("expected values for `{name}` are: {possibilities}"));
}
// Suggest the most probable if we found one
@ -801,7 +801,7 @@ pub trait LintContext: Sized {
db.span_suggestion(value_span, "did you mean", format!("\"{best_match}\""), Applicability::MaybeIncorrect);
}
} else {
db.note(&format!("no expected value for `{name}`"));
db.note(format!("no expected value for `{name}`"));
if name != sym::feature {
db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect);
}

View file

@ -428,7 +428,7 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
for early_lint in lints {
sess.delay_span_bug(
early_lint.span,
&format!(
format!(
"failed to process buffered lint here (dummy = {})",
id == ast::DUMMY_NODE_ID
),