1
Fork 0

Avoid &format("...") calls in error message code.

Error message all end up passing into a function as an `impl
Into<{D,Subd}iagnosticMessage>`. If an error message is creatd as
`&format("...")` that means we allocate a string (in the `format!`
call), then take a reference, and then clone (allocating again) the
reference to produce the `{D,Subd}iagnosticMessage`, which is silly.

This commit removes the leading `&` from a lot of these cases. This
means the original `String` is moved into the
`{D,Subd}iagnosticMessage`, avoiding the double allocations. This
requires changing some function argument types from `&str` to `String`
(when all arguments are `String`) or `impl
Into<{D,Subd}iagnosticMessage>` (when some arguments are `String` and
some are `&str`).
This commit is contained in:
Nicholas Nethercote 2023-05-16 16:04:03 +10:00
parent 87a2bc027c
commit 01e33a3600
37 changed files with 139 additions and 133 deletions

View file

@ -15,7 +15,8 @@ use rustc_attr::{self as attr, Deprecation, Stability};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::{self, Lrc};
use rustc_errors::{
Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan, PResult,
Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic,
MultiSpan, PResult,
};
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, RegisteredTools};
@ -1110,7 +1111,7 @@ impl<'a> ExtCtxt<'a> {
pub fn struct_span_err<S: Into<MultiSpan>>(
&self,
sp: S,
msg: &str,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
self.sess.parse_sess.span_diagnostic.struct_span_err(sp, msg)
}
@ -1132,14 +1133,14 @@ impl<'a> ExtCtxt<'a> {
/// Compilation will be stopped in the near future (at the end of
/// the macro expansion phase).
#[rustc_lint_diagnostics]
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
self.sess.parse_sess.span_diagnostic.span_err(sp, msg);
}
#[rustc_lint_diagnostics]
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
self.sess.parse_sess.span_diagnostic.span_warn(sp, msg);
}
pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! {
self.sess.parse_sess.span_diagnostic.span_bug(sp, msg);
}
pub fn trace_macros_diag(&mut self) {

View file

@ -1664,7 +1664,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
&UNUSED_ATTRIBUTES,
attr.span,
self.cx.current_expansion.lint_node_id,
&format!("unused attribute `{}`", attr_name),
format!("unused attribute `{}`", attr_name),
BuiltinLintDiagnostics::UnusedBuiltinAttribute {
attr_name,
macro_name: pprust::path_to_string(&call.path),

View file

@ -48,7 +48,7 @@ pub(super) fn failed_to_match_macro<'cx>(
let span = token.span.substitute_dummy(sp);
let mut err = cx.struct_span_err(span, &parse_failure_msg(&token));
let mut err = cx.struct_span_err(span, parse_failure_msg(&token));
err.span_label(span, label);
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
@ -170,7 +170,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
}
Error(err_sp, msg) => {
let span = err_sp.substitute_dummy(self.root_span);
self.cx.struct_span_err(span, msg).emit();
self.cx.struct_span_err(span, msg.as_str()).emit();
self.result = Some(DummyResult::any(span));
}
ErrorReported(_) => self.result = Some(DummyResult::any(self.root_span)),

View file

@ -110,7 +110,7 @@ use crate::mbe::{KleeneToken, TokenTree};
use rustc_ast::token::{Delimiter, Token, TokenKind};
use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::MultiSpan;
use rustc_errors::{DiagnosticMessage, MultiSpan};
use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
use rustc_session::parse::ParseSess;
use rustc_span::symbol::kw;
@ -593,7 +593,7 @@ fn check_ops_is_prefix(
return;
}
}
buffer_lint(sess, span.into(), node_id, &format!("unknown macro variable `{}`", name));
buffer_lint(sess, span.into(), node_id, format!("unknown macro variable `{}`", name));
}
/// Returns whether `binder_ops` is a prefix of `occurrence_ops`.
@ -626,7 +626,7 @@ fn ops_is_prefix(
if i >= occurrence_ops.len() {
let mut span = MultiSpan::from_span(span);
span.push_span_label(binder.span, "expected repetition");
let message = &format!("variable '{}' is still repeating at this depth", name);
let message = format!("variable '{}' is still repeating at this depth", name);
buffer_lint(sess, span, node_id, message);
return;
}
@ -642,7 +642,12 @@ fn ops_is_prefix(
}
}
fn buffer_lint(sess: &ParseSess, span: MultiSpan, node_id: NodeId, message: &str) {
fn buffer_lint(
sess: &ParseSess,
span: MultiSpan,
node_id: NodeId,
message: impl Into<DiagnosticMessage>,
) {
// Macros loaded from other crates have dummy node ids.
if node_id != DUMMY_NODE_ID {
sess.buffer_lint(&META_VARIABLE_MISUSE, span, node_id, message);

View file

@ -510,7 +510,7 @@ fn out_of_bounds_err<'a>(
must be less than {max}"
)
};
cx.struct_span_err(span, &msg)
cx.struct_span_err(span, msg)
}
fn transcribe_metavar_expr<'a>(