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:
@@ -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,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user