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

@ -791,7 +791,7 @@ macro_rules! struct_span_err {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
$session.struct_span_err_with_code(
$span,
&format!($($message)*),
format!($($message)*),
$crate::error_code!($code),
)
})

View file

@ -601,7 +601,7 @@ impl Emitter for SilentEmitter {
if d.level == Level::Fatal {
let mut d = d.clone();
if let Some(ref note) = self.fatal_note {
d.note(note);
d.note(note.clone());
}
self.fatal_handler.emit_diagnostic(&mut d);
}

View file

@ -1462,10 +1462,10 @@ impl HandlerInner {
DiagnosticMessage::Str(warnings),
)),
(_, 0) => {
let _ = self.fatal(&errors);
let _ = self.fatal(errors);
}
(_, _) => {
let _ = self.fatal(&format!("{}; {}", &errors, &warnings));
let _ = self.fatal(format!("{}; {}", &errors, &warnings));
}
}
@ -1486,18 +1486,18 @@ impl HandlerInner {
error_codes.sort();
if error_codes.len() > 1 {
let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
self.failure(&format!(
self.failure(format!(
"Some errors have detailed explanations: {}{}",
error_codes[..limit].join(", "),
if error_codes.len() > 9 { "..." } else { "." }
));
self.failure(&format!(
self.failure(format!(
"For more information about an error, try \
`rustc --explain {}`.",
&error_codes[0]
));
} else {
self.failure(&format!(
self.failure(format!(
"For more information about this error, try \
`rustc --explain {}`.",
&error_codes[0]
@ -1663,7 +1663,7 @@ impl HandlerInner {
if bug.level != Level::DelayedBug {
// NOTE(eddyb) not panicking here because we're already producing
// an ICE, and the more information the merrier.
bug.note(&format!(
bug.note(format!(
"`flushed_delayed` got diagnostic with level {:?}, \
instead of the expected `DelayedBug`",
bug.level,
@ -1732,7 +1732,7 @@ impl DelayedDiagnostic {
}
fn decorate(mut self) -> Diagnostic {
self.inner.note(&format!("delayed at {}", self.note));
self.inner.note(format!("delayed at {}", self.note));
self.inner
}
}
@ -1831,7 +1831,7 @@ pub fn add_elided_lifetime_in_path_suggestion(
if incl_angl_brckt { format!("<{}>", anon_lts) } else { format!("{}, ", anon_lts) };
diag.span_suggestion_verbose(
insertion_span.shrink_to_hi(),
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
format!("indicate the anonymous lifetime{}", pluralize!(n)),
suggestion,
Applicability::MachineApplicable,
);