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

@ -12,7 +12,7 @@ use tracing::debug;
pub trait LayoutCalculator { pub trait LayoutCalculator {
type TargetDataLayoutRef: Borrow<TargetDataLayout>; type TargetDataLayoutRef: Borrow<TargetDataLayout>;
fn delay_bug(&self, txt: &str); fn delay_bug(&self, txt: String);
fn current_data_layout(&self) -> Self::TargetDataLayoutRef; fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutS { fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutS {
@ -969,7 +969,7 @@ fn univariant(
for &i in &inverse_memory_index { for &i in &inverse_memory_index {
let field = &fields[i]; let field = &fields[i];
if !sized { if !sized {
this.delay_bug(&format!( this.delay_bug(format!(
"univariant: field #{} comes after unsized field", "univariant: field #{} comes after unsized field",
offsets.len(), offsets.len(),
)); ));

View file

@ -430,7 +430,7 @@ pub(super) fn dump_annotation<'tcx>(
fn for_each_region_constraint<'tcx>( fn for_each_region_constraint<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
closure_region_requirements: &ClosureRegionRequirements<'tcx>, closure_region_requirements: &ClosureRegionRequirements<'tcx>,
with_msg: &mut dyn FnMut(&str) -> io::Result<()>, with_msg: &mut dyn FnMut(String) -> io::Result<()>,
) -> io::Result<()> { ) -> io::Result<()> {
for req in &closure_region_requirements.outlives_requirements { for req in &closure_region_requirements.outlives_requirements {
let subject = match req.subject { let subject = match req.subject {
@ -439,7 +439,7 @@ fn for_each_region_constraint<'tcx>(
format!("{:?}", ty.instantiate(tcx, |vid| tcx.mk_re_var(vid))) format!("{:?}", ty.instantiate(tcx, |vid| tcx.mk_re_var(vid)))
} }
}; };
with_msg(&format!("where {}: {:?}", subject, req.outlived_free_region,))?; with_msg(format!("where {}: {:?}", subject, req.outlived_free_region,))?;
} }
Ok(()) Ok(())
} }

View file

@ -71,7 +71,7 @@ macro_rules! span_mirbug {
$crate::type_check::mirbug( $crate::type_check::mirbug(
$context.tcx(), $context.tcx(),
$context.last_span, $context.last_span,
&format!( format!(
"broken MIR in {:?} ({:?}): {}", "broken MIR in {:?} ({:?}): {}",
$context.body().source.def_id(), $context.body().source.def_id(),
$elem, $elem,
@ -274,7 +274,7 @@ fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
} }
#[track_caller] #[track_caller]
fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: &str) { fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: String) {
// We sometimes see MIR failures (notably predicate failures) due to // We sometimes see MIR failures (notably predicate failures) due to
// the fact that we check rvalue sized predicates here. So use `delay_span_bug` // the fact that we check rvalue sized predicates here. So use `delay_span_bug`
// to avoid reporting bugs in those cases. // to avoid reporting bugs in those cases.

View file

@ -550,7 +550,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
if !parser.errors.is_empty() { if !parser.errors.is_empty() {
let err = parser.errors.remove(0); let err = parser.errors.remove(0);
let err_sp = template_span.from_inner(InnerSpan::new(err.span.start, err.span.end)); let err_sp = template_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
let msg = &format!("invalid asm template string: {}", err.description); let msg = format!("invalid asm template string: {}", err.description);
let mut e = ecx.struct_span_err(err_sp, msg); let mut e = ecx.struct_span_err(err_sp, msg);
e.span_label(err_sp, err.label + " in asm template string"); e.span_label(err_sp, err.label + " in asm template string");
if let Some(note) = err.note { if let Some(note) = err.note {
@ -585,7 +585,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|| args.reg_args.contains(idx) || args.reg_args.contains(idx)
{ {
let msg = format!("invalid reference to argument at index {}", idx); let msg = format!("invalid reference to argument at index {}", idx);
let mut err = ecx.struct_span_err(span, &msg); let mut err = ecx.struct_span_err(span, msg);
err.span_label(span, "from here"); err.span_label(span, "from here");
let positional_args = args.operands.len() let positional_args = args.operands.len()
@ -638,7 +638,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
ecx.struct_span_err( ecx.struct_span_err(
template_span template_span
.from_inner(InnerSpan::new(span.start, span.end)), .from_inner(InnerSpan::new(span.start, span.end)),
&msg, msg,
) )
.emit(); .emit();
None None

View file

@ -145,7 +145,7 @@ fn cs_clone_simple(
} }
_ => cx.span_bug( _ => cx.span_bug(
trait_span, trait_span,
&format!("unexpected substructure in simple `derive({})`", name), format!("unexpected substructure in simple `derive({})`", name),
), ),
} }
} }
@ -179,10 +179,10 @@ fn cs_clone(
vdata = &variant.data; vdata = &variant.data;
} }
EnumTag(..) | AllFieldlessEnum(..) => { EnumTag(..) | AllFieldlessEnum(..) => {
cx.span_bug(trait_span, &format!("enum tags in `derive({})`", name,)) cx.span_bug(trait_span, format!("enum tags in `derive({})`", name,))
} }
StaticEnum(..) | StaticStruct(..) => { StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, &format!("associated function in `derive({})`", name)) cx.span_bug(trait_span, format!("associated function in `derive({})`", name))
} }
} }
@ -194,7 +194,7 @@ fn cs_clone(
let Some(ident) = field.name else { let Some(ident) = field.name else {
cx.span_bug( cx.span_bug(
trait_span, trait_span,
&format!("unnamed field in normal struct in `derive({})`", name,), format!("unnamed field in normal struct in `derive({})`", name,),
); );
}; };
let call = subcall(cx, field); let call = subcall(cx, field);

View file

@ -1591,7 +1591,7 @@ impl<'a> TraitDef<'a> {
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE, BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
sp, sp,
ast::CRATE_NODE_ID, ast::CRATE_NODE_ID,
&format!( format!(
"{} slice in a packed struct that derives a built-in trait", "{} slice in a packed struct that derives a built-in trait",
ty ty
), ),

View file

@ -814,7 +814,7 @@ fn report_invalid_references(
}; };
e = ecx.struct_span_err( e = ecx.struct_span_err(
span, span,
&format!("invalid reference to positional {} ({})", arg_list, num_args_desc), format!("invalid reference to positional {} ({})", arg_list, num_args_desc),
); );
e.note("positional arguments are zero-based"); e.note("positional arguments are zero-based");
} }

View file

@ -188,12 +188,12 @@ pub fn expand_include_str(
base::MacEager::expr(cx.expr_str(sp, interned_src)) base::MacEager::expr(cx.expr_str(sp, interned_src))
} }
Err(_) => { Err(_) => {
cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display())); cx.span_err(sp, format!("{} wasn't a utf-8 file", file.display()));
DummyResult::any(sp) DummyResult::any(sp)
} }
}, },
Err(e) => { Err(e) => {
cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e));
DummyResult::any(sp) DummyResult::any(sp)
} }
} }
@ -221,7 +221,7 @@ pub fn expand_include_bytes(
base::MacEager::expr(expr) base::MacEager::expr(expr)
} }
Err(e) => { Err(e) => {
cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e));
DummyResult::any(sp) DummyResult::any(sp)
} }
} }

View file

@ -227,7 +227,7 @@ pub(crate) fn write_ir_file(
// Using early_warn as no Session is available here // Using early_warn as no Session is available here
rustc_session::early_warn( rustc_session::early_warn(
rustc_session::config::ErrorOutputType::default(), rustc_session::config::ErrorOutputType::default(),
&format!("error writing ir file: {}", err), format!("error writing ir file: {}", err),
); );
} }
} }

View file

@ -25,7 +25,7 @@ pub fn arg_expand_all(at_args: &[String]) -> Vec<String> {
Ok(arg) => args.extend(arg), Ok(arg) => args.extend(arg),
Err(err) => rustc_session::early_error( Err(err) => rustc_session::early_error(
rustc_session::config::ErrorOutputType::default(), rustc_session::config::ErrorOutputType::default(),
&format!("Failed to load argument file: {err}"), format!("Failed to load argument file: {err}"),
), ),
} }
} }

View file

@ -322,7 +322,7 @@ fn run_compiler(
1 => panic!("make_input should have provided valid inputs"), 1 => panic!("make_input should have provided valid inputs"),
_ => early_error( _ => early_error(
config.opts.error_format, config.opts.error_format,
&format!( format!(
"multiple input filenames provided (first two filenames are `{}` and `{}`)", "multiple input filenames provided (first two filenames are `{}` and `{}`)",
matches.free[0], matches.free[1], matches.free[0], matches.free[1],
), ),
@ -527,7 +527,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
} }
} }
Err(InvalidErrorCode) => { Err(InvalidErrorCode) => {
early_error(output, &format!("{code} is not a valid error code")); early_error(output, format!("{code} is not a valid error code"));
} }
} }
} }
@ -1102,7 +1102,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
.map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")), .map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
_ => None, _ => None,
}; };
early_error(ErrorOutputType::default(), &msg.unwrap_or_else(|| e.to_string())); early_error(ErrorOutputType::default(), msg.unwrap_or_else(|| e.to_string()));
}); });
// For all options we just parsed, we check a few aspects: // For all options we just parsed, we check a few aspects:
@ -1250,7 +1250,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
#[cfg(windows)] #[cfg(windows)]
if let Some(msg) = info.payload().downcast_ref::<String>() { if let Some(msg) = info.payload().downcast_ref::<String>() {
if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") { if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") {
early_error_no_abort(ErrorOutputType::default(), &msg); early_error_no_abort(ErrorOutputType::default(), msg.as_str());
return; return;
} }
}; };
@ -1342,7 +1342,7 @@ pub fn init_rustc_env_logger() {
/// other than `RUSTC_LOG`. /// other than `RUSTC_LOG`.
pub fn init_env_logger(env: &str) { pub fn init_env_logger(env: &str) {
if let Err(error) = rustc_log::init_env_logger(env) { if let Err(error) = rustc_log::init_env_logger(env) {
early_error(ErrorOutputType::default(), &error.to_string()); early_error(ErrorOutputType::default(), error.to_string());
} }
} }
@ -1409,7 +1409,7 @@ pub fn main() -> ! {
arg.into_string().unwrap_or_else(|arg| { arg.into_string().unwrap_or_else(|arg| {
early_error( early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!("argument {i} is not valid Unicode: {arg:?}"), format!("argument {i} is not valid Unicode: {arg:?}"),
) )
}) })
}) })

View file

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

View file

@ -1664,7 +1664,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
&UNUSED_ATTRIBUTES, &UNUSED_ATTRIBUTES,
attr.span, attr.span,
self.cx.current_expansion.lint_node_id, self.cx.current_expansion.lint_node_id,
&format!("unused attribute `{}`", attr_name), format!("unused attribute `{}`", attr_name),
BuiltinLintDiagnostics::UnusedBuiltinAttribute { BuiltinLintDiagnostics::UnusedBuiltinAttribute {
attr_name, attr_name,
macro_name: pprust::path_to_string(&call.path), 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 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); err.span_label(span, label);
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) { 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"); 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) => { Error(err_sp, msg) => {
let span = err_sp.substitute_dummy(self.root_span); 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)); self.result = Some(DummyResult::any(span));
} }
ErrorReported(_) => self.result = Some(DummyResult::any(self.root_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::token::{Delimiter, Token, TokenKind};
use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast::{NodeId, DUMMY_NODE_ID};
use rustc_data_structures::fx::FxHashMap; 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::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::symbol::kw; use rustc_span::symbol::kw;
@ -593,7 +593,7 @@ fn check_ops_is_prefix(
return; 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`. /// Returns whether `binder_ops` is a prefix of `occurrence_ops`.
@ -626,7 +626,7 @@ fn ops_is_prefix(
if i >= occurrence_ops.len() { if i >= occurrence_ops.len() {
let mut span = MultiSpan::from_span(span); let mut span = MultiSpan::from_span(span);
span.push_span_label(binder.span, "expected repetition"); 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); buffer_lint(sess, span, node_id, message);
return; 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. // Macros loaded from other crates have dummy node ids.
if node_id != DUMMY_NODE_ID { if node_id != DUMMY_NODE_ID {
sess.buffer_lint(&META_VARIABLE_MISUSE, span, node_id, message); 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}" must be less than {max}"
) )
}; };
cx.struct_span_err(span, &msg) cx.struct_span_err(span, msg)
} }
fn transcribe_metavar_expr<'a>( fn transcribe_metavar_expr<'a>(

View file

@ -24,7 +24,7 @@ fn generic_arg_mismatch_err(
arg: &GenericArg<'_>, arg: &GenericArg<'_>,
param: &GenericParamDef, param: &GenericParamDef,
possible_ordering_error: bool, possible_ordering_error: bool,
help: Option<&str>, help: Option<String>,
) -> ErrorGuaranteed { ) -> ErrorGuaranteed {
let sess = tcx.sess; let sess = tcx.sess;
let mut err = struct_span_err!( let mut err = struct_span_err!(
@ -300,7 +300,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
arg, arg,
param, param,
!args_iter.clone().is_sorted_by_key(|arg| arg.to_ord()), !args_iter.clone().is_sorted_by_key(|arg| arg.to_ord()),
Some(&format!( Some(format!(
"reorder the arguments: {}: `<{}>`", "reorder the arguments: {}: `<{}>`",
param_types_present param_types_present
.into_iter() .into_iter()

View file

@ -164,7 +164,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else { let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else {
return tcx.ty_error_with_message( return tcx.ty_error_with_message(
tcx.def_span(def_id), tcx.def_span(def_id),
&format!("unable to find type-dependent def for {:?}", parent_node_id), format!("unable to find type-dependent def for {:?}", parent_node_id),
); );
}; };
let idx = segment let idx = segment
@ -205,14 +205,14 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
} else { } else {
return tcx.ty_error_with_message( return tcx.ty_error_with_message(
tcx.def_span(def_id), tcx.def_span(def_id),
&format!("unable to find const parent for {} in pat {:?}", hir_id, pat), format!("unable to find const parent for {} in pat {:?}", hir_id, pat),
); );
} }
} }
_ => { _ => {
return tcx.ty_error_with_message( return tcx.ty_error_with_message(
tcx.def_span(def_id), tcx.def_span(def_id),
&format!("unexpected const parent path {:?}", parent_node), format!("unexpected const parent path {:?}", parent_node),
); );
} }
}; };
@ -243,7 +243,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
None => { None => {
return tcx.ty_error_with_message( return tcx.ty_error_with_message(
tcx.def_span(def_id), tcx.def_span(def_id),
&format!("unexpected anon const res {:?} in path: {:?}", segment.res, path), format!("unexpected anon const res {:?} in path: {:?}", segment.res, path),
); );
} }
}; };
@ -253,7 +253,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
_ => return tcx.ty_error_with_message( _ => return tcx.ty_error_with_message(
tcx.def_span(def_id), tcx.def_span(def_id),
&format!("unexpected const parent in type_of(): {parent_node:?}"), format!("unexpected const parent in type_of(): {parent_node:?}"),
), ),
}; };
@ -279,7 +279,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
} else { } else {
return tcx.ty_error_with_message( return tcx.ty_error_with_message(
tcx.def_span(def_id), tcx.def_span(def_id),
&format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"), format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"),
); );
} }
} }

View file

@ -2468,7 +2468,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{ {
self.suggest_method_call( self.suggest_method_call(
&mut err, &mut err,
&format!("a method `{field}` also exists, call it with parentheses"), format!("a method `{field}` also exists, call it with parentheses"),
field, field,
expr_t, expr_t,
expr, expr,

View file

@ -158,7 +158,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
let Some((ty, n)) = autoderef.nth(pick.autoderefs) else { let Some((ty, n)) = autoderef.nth(pick.autoderefs) else {
return self.tcx.ty_error_with_message( return self.tcx.ty_error_with_message(
rustc_span::DUMMY_SP, rustc_span::DUMMY_SP,
&format!("failed autoderef {}", pick.autoderefs), format!("failed autoderef {}", pick.autoderefs),
); );
}; };
assert_eq!(n, pick.autoderefs); assert_eq!(n, pick.autoderefs);

View file

@ -13,7 +13,7 @@ pub use self::MethodError::*;
use crate::errors::OpMethodGenericParams; use crate::errors::OpMethodGenericParams;
use crate::FnCtxt; use crate::FnCtxt;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, Diagnostic, SubdiagnosticMessage};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def::{CtorOf, DefKind, Namespace};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -130,7 +130,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_method_call( pub(crate) fn suggest_method_call(
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,
msg: &str, msg: impl Into<SubdiagnosticMessage> + std::fmt::Debug,
method_name: Ident, method_name: Ident,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
call_expr: &hir::Expr<'tcx>, call_expr: &hir::Expr<'tcx>,

View file

@ -237,7 +237,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// error has been emitted. (#64638) // error has been emitted. (#64638)
self.fcx.tcx.ty_error_with_message( self.fcx.tcx.ty_error_with_message(
e.span, e.span,
&format!("bad index {:?} for base: `{:?}`", index, base), format!("bad index {:?} for base: `{:?}`", index, base),
) )
}); });
let index_ty = self.fcx.resolve_vars_if_possible(index_ty); let index_ty = self.fcx.resolve_vars_if_possible(index_ty);

View file

@ -80,7 +80,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
($reason: expr) => { ($reason: expr) => {
early_error( early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!(concat!("invalid `--cfg` argument: `{}` (", $reason, ")"), s), format!(concat!("invalid `--cfg` argument: `{}` (", $reason, ")"), s),
); );
}; };
} }
@ -139,10 +139,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
($reason: expr) => { ($reason: expr) => {
early_error( early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!( format!(concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), s),
concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
s
),
) )
}; };
} }

View file

@ -88,7 +88,7 @@ pub fn create_session(
) { ) {
Ok(bundle) => bundle, Ok(bundle) => bundle,
Err(e) => { Err(e) => {
early_error(sopts.error_format, &format!("failed to load fluent bundle: {e}")); early_error(sopts.error_format, format!("failed to load fluent bundle: {e}"));
} }
}; };
@ -220,13 +220,13 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
fn load_backend_from_dylib(path: &Path) -> MakeBackendFn { fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| { let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
let err = format!("couldn't load codegen backend {path:?}: {err}"); let err = format!("couldn't load codegen backend {path:?}: {err}");
early_error(ErrorOutputType::default(), &err); early_error(ErrorOutputType::default(), err);
}); });
let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") } let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
let err = format!("couldn't load codegen backend: {e}"); let err = format!("couldn't load codegen backend: {e}");
early_error(ErrorOutputType::default(), &err); early_error(ErrorOutputType::default(), err);
}); });
// Intentionally leak the dynamic library. We can't ever unload it // Intentionally leak the dynamic library. We can't ever unload it
@ -320,7 +320,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
"failed to find a `codegen-backends` folder \ "failed to find a `codegen-backends` folder \
in the sysroot candidates:\n* {candidates}" in the sysroot candidates:\n* {candidates}"
); );
early_error(ErrorOutputType::default(), &err); early_error(ErrorOutputType::default(), err);
}); });
info!("probing {} for a codegen backend", sysroot.display()); info!("probing {} for a codegen backend", sysroot.display());
@ -331,7 +331,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
sysroot.display(), sysroot.display(),
e e
); );
early_error(ErrorOutputType::default(), &err); early_error(ErrorOutputType::default(), err);
}); });
let mut file: Option<PathBuf> = None; let mut file: Option<PathBuf> = None;
@ -359,7 +359,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
prev.display(), prev.display(),
path.display() path.display()
); );
early_error(ErrorOutputType::default(), &err); early_error(ErrorOutputType::default(), err);
} }
file = Some(path.clone()); file = Some(path.clone());
} }
@ -368,7 +368,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
Some(ref s) => load_backend_from_dylib(s), Some(ref s) => load_backend_from_dylib(s),
None => { None => {
let err = format!("unsupported builtin codegen backend `{backend_name}`"); let err = format!("unsupported builtin codegen backend `{backend_name}`");
early_error(ErrorOutputType::default(), &err); early_error(ErrorOutputType::default(), err);
} }
} }
} }

View file

@ -943,7 +943,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
lint::builtin::UNUSED_CRATE_DEPENDENCIES, lint::builtin::UNUSED_CRATE_DEPENDENCIES,
span, span,
ast::CRATE_NODE_ID, ast::CRATE_NODE_ID,
&format!( format!(
"external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`", "external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`",
name, name,
self.tcx.crate_name(LOCAL_CRATE), self.tcx.crate_name(LOCAL_CRATE),

View file

@ -702,7 +702,11 @@ impl<'tcx> TyCtxt<'tcx> {
/// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
/// ensure it gets used. /// ensure it gets used.
#[track_caller] #[track_caller]
pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> { pub fn ty_error_with_message<S: Into<MultiSpan>>(
self,
span: S,
msg: impl Into<DiagnosticMessage>,
) -> Ty<'tcx> {
let reported = self.sess.delay_span_bug(span, msg); let reported = self.sess.delay_span_bug(span, msg);
self.mk_ty_from_kind(Error(reported)) self.mk_ty_from_kind(Error(reported))
} }
@ -2435,7 +2439,7 @@ impl<'tcx> TyCtxtAt<'tcx> {
/// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
/// ensure it gets used. /// ensure it gets used.
#[track_caller] #[track_caller]
pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> { pub fn ty_error_with_message(self, msg: impl Into<DiagnosticMessage>) -> Ty<'tcx> {
self.tcx.ty_error_with_message(self.span, msg) self.tcx.ty_error_with_message(self.span, msg)
} }
} }

View file

@ -268,7 +268,7 @@ pub struct LayoutCx<'tcx, C> {
impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> { impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
type TargetDataLayoutRef = &'tcx TargetDataLayout; type TargetDataLayoutRef = &'tcx TargetDataLayout;
fn delay_bug(&self, txt: &str) { fn delay_bug(&self, txt: String) {
self.tcx.sess.delay_span_bug(DUMMY_SP, txt); self.tcx.sess.delay_span_bug(DUMMY_SP, txt);
} }

View file

@ -662,7 +662,7 @@ impl<'a> StringReader<'a> {
&RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, &RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
prefix_span, prefix_span,
ast::CRATE_NODE_ID, ast::CRATE_NODE_ID,
&format!("prefix `{prefix}` is unknown"), format!("prefix `{prefix}` is unknown"),
BuiltinLintDiagnostics::ReservedPrefix(prefix_span), BuiltinLintDiagnostics::ReservedPrefix(prefix_span),
); );
} }

View file

@ -186,7 +186,7 @@ fn emit_malformed_attribute(
suggestions.push(code); suggestions.push(code);
} }
if should_warn(name) { if should_warn(name) {
sess.buffer_lint(&ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, &msg); sess.buffer_lint(&ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, msg);
} else { } else {
sess.span_diagnostic sess.span_diagnostic
.struct_span_err(span, error_msg) .struct_span_err(span, error_msg)

View file

@ -1319,7 +1319,7 @@ pub(super) fn build_target_config(
let (target, target_warnings) = target_result.unwrap_or_else(|e| { let (target, target_warnings) = target_result.unwrap_or_else(|e| {
early_error( early_error(
opts.error_format, opts.error_format,
&format!( format!(
"Error loading target specification: {}. \ "Error loading target specification: {}. \
Run `rustc --print target-list` for a list of built-in targets", Run `rustc --print target-list` for a list of built-in targets",
e e
@ -1327,15 +1327,14 @@ pub(super) fn build_target_config(
) )
}); });
for warning in target_warnings.warning_messages() { for warning in target_warnings.warning_messages() {
early_warn(opts.error_format, &warning) early_warn(opts.error_format, warning)
} }
if !matches!(target.pointer_width, 16 | 32 | 64) { if !matches!(target.pointer_width, 16 | 32 | 64) {
early_error( early_error(
opts.error_format, opts.error_format,
&format!( format!(
"target specification was invalid: \ "target specification was invalid: unrecognized target-pointer-width {}",
unrecognized target-pointer-width {}",
target.pointer_width target.pointer_width
), ),
) )
@ -1599,7 +1598,7 @@ pub fn get_cmd_lint_options(
let lint_cap = matches.opt_str("cap-lints").map(|cap| { let lint_cap = matches.opt_str("cap-lints").map(|cap| {
lint::Level::from_str(&cap) lint::Level::from_str(&cap)
.unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{cap}`"))) .unwrap_or_else(|| early_error(error_format, format!("unknown lint level: `{cap}`")))
}); });
(lint_opts, describe_lints, lint_cap) (lint_opts, describe_lints, lint_cap)
@ -1616,7 +1615,7 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
Some(arg) => early_error( Some(arg) => early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!( format!(
"argument for `--color` must be auto, \ "argument for `--color` must be auto, \
always or never (instead was `{arg}`)" always or never (instead was `{arg}`)"
), ),
@ -1691,7 +1690,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
"future-incompat" => json_future_incompat = true, "future-incompat" => json_future_incompat = true,
s => early_error( s => early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!("unknown `--json` option `{s}`"), format!("unknown `--json` option `{s}`"),
), ),
} }
} }
@ -1729,7 +1728,7 @@ pub fn parse_error_format(
Some(arg) => early_error( Some(arg) => early_error(
ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)), ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
&format!( format!(
"argument for `--error-format` must be `human`, `json` or \ "argument for `--error-format` must be `human`, `json` or \
`short` (instead was `{arg}`)" `short` (instead was `{arg}`)"
), ),
@ -1763,7 +1762,7 @@ pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| { Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
early_error( early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!( format!(
"argument for `--edition` must be one of: \ "argument for `--edition` must be one of: \
{EDITION_NAME_LIST}. (instead was `{arg}`)" {EDITION_NAME_LIST}. (instead was `{arg}`)"
), ),
@ -1782,7 +1781,7 @@ pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
} else { } else {
format!("edition {edition} is unstable and only available with -Z unstable-options") format!("edition {edition} is unstable and only available with -Z unstable-options")
}; };
early_error(ErrorOutputType::default(), &msg) early_error(ErrorOutputType::default(), msg)
} }
edition edition
@ -1827,7 +1826,7 @@ fn parse_output_types(
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| { let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
early_error( early_error(
error_format, error_format,
&format!( format!(
"unknown emission type: `{shorthand}` - expected one of: {display}", "unknown emission type: `{shorthand}` - expected one of: {display}",
display = OutputType::shorthands_display(), display = OutputType::shorthands_display(),
), ),
@ -1866,7 +1865,7 @@ fn should_override_cgus_and_disable_thinlto(
for ot in &incompatible { for ot in &incompatible {
early_warn( early_warn(
error_format, error_format,
&format!( format!(
"`--emit={ot}` with `-o` incompatible with \ "`--emit={ot}` with `-o` incompatible with \
`-C codegen-units=N` for N > 1", `-C codegen-units=N` for N > 1",
), ),
@ -1970,7 +1969,7 @@ fn collect_print_requests(
let prints = prints.join(", "); let prints = prints.join(", ");
early_error( early_error(
error_format, error_format,
&format!("unknown print request `{req}`. Valid print requests are: {prints}"), format!("unknown print request `{req}`. Valid print requests are: {prints}"),
); );
} }
} }
@ -1987,7 +1986,7 @@ pub fn parse_target_triple(
Some(target) if target.ends_with(".json") => { Some(target) if target.ends_with(".json") => {
let path = Path::new(&target); let path = Path::new(&target);
TargetTriple::from_path(path).unwrap_or_else(|_| { TargetTriple::from_path(path).unwrap_or_else(|_| {
early_error(error_format, &format!("target file {path:?} does not exist")) early_error(error_format, format!("target file {path:?} does not exist"))
}) })
} }
Some(target) => TargetTriple::TargetTriple(target), Some(target) => TargetTriple::TargetTriple(target),
@ -2028,7 +2027,7 @@ fn parse_opt_level(
arg => { arg => {
early_error( early_error(
error_format, error_format,
&format!( format!(
"optimization level needs to be \ "optimization level needs to be \
between 0-3, s or z (instead was `{arg}`)" between 0-3, s or z (instead was `{arg}`)"
), ),
@ -2059,7 +2058,7 @@ pub(crate) fn parse_assert_incr_state(
Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded), Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded),
Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded), Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
Some(s) => { Some(s) => {
early_error(error_format, &format!("unexpected incremental state assertion value: {s}")) early_error(error_format, format!("unexpected incremental state assertion value: {s}"))
} }
None => None, None => None,
} }
@ -2086,13 +2085,13 @@ fn parse_native_lib_kind(
} else { } else {
", the `-Z unstable-options` flag must also be passed to use it" ", the `-Z unstable-options` flag must also be passed to use it"
}; };
early_error(error_format, &format!("library kind `link-arg` is unstable{why}")) early_error(error_format, format!("library kind `link-arg` is unstable{why}"))
} }
NativeLibKind::LinkArg NativeLibKind::LinkArg
} }
_ => early_error( _ => early_error(
error_format, error_format,
&format!( format!(
"unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg" "unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
), ),
), ),
@ -2127,16 +2126,13 @@ fn parse_native_lib_modifiers(
} else { } else {
", the `-Z unstable-options` flag must also be passed to use it" ", the `-Z unstable-options` flag must also be passed to use it"
}; };
early_error( early_error(error_format, format!("linking modifier `{modifier}` is unstable{why}"))
error_format,
&format!("linking modifier `{modifier}` is unstable{why}"),
)
} }
}; };
let assign_modifier = |dst: &mut Option<bool>| { let assign_modifier = |dst: &mut Option<bool>| {
if dst.is_some() { if dst.is_some() {
let msg = format!("multiple `{modifier}` modifiers in a single `-l` option"); let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
early_error(error_format, &msg) early_error(error_format, msg)
} else { } else {
*dst = Some(value); *dst = Some(value);
} }
@ -2173,7 +2169,7 @@ fn parse_native_lib_modifiers(
// string, like `modifiers = ""`. // string, like `modifiers = ""`.
_ => early_error( _ => early_error(
error_format, error_format,
&format!( format!(
"unknown linking modifier `{modifier}`, expected one \ "unknown linking modifier `{modifier}`, expected one \
of: bundle, verbatim, whole-archive, as-needed" of: bundle, verbatim, whole-archive, as-needed"
), ),
@ -2303,7 +2299,7 @@ pub fn parse_externs(
} }
"nounused" => nounused_dep = true, "nounused" => nounused_dep = true,
"force" => force = true, "force" => force = true,
_ => early_error(error_format, &format!("unknown --extern option `{opt}`")), _ => early_error(error_format, format!("unknown --extern option `{opt}`")),
} }
} }
} }
@ -2369,7 +2365,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let unparsed_crate_types = matches.opt_strs("crate-type"); let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types) let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(error_format, &e)); .unwrap_or_else(|e| early_error(error_format, e));
let mut unstable_opts = UnstableOptions::build(matches, error_format); let mut unstable_opts = UnstableOptions::build(matches, error_format);
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
@ -2597,7 +2593,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}; };
let working_dir = std::env::current_dir().unwrap_or_else(|e| { let working_dir = std::env::current_dir().unwrap_or_else(|e| {
early_error(error_format, &format!("Current directory is invalid: {e}")); early_error(error_format, format!("Current directory is invalid: {e}"));
}); });
let remap = FilePathMapping::new(remap_path_prefix.clone()); let remap = FilePathMapping::new(remap_path_prefix.clone());
@ -2669,7 +2665,7 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
"mir-cfg" => MirCFG, "mir-cfg" => MirCFG,
name => early_error( name => early_error(
efmt, efmt,
&format!( format!(
"argument to `unpretty` must be one of `normal`, `identified`, \ "argument to `unpretty` must be one of `normal`, `identified`, \
`expanded`, `expanded,identified`, `expanded,hygiene`, \ `expanded`, `expanded,identified`, `expanded,hygiene`, \
`ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \ `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
@ -2747,7 +2743,7 @@ pub mod nightly_options {
if opt.name != "Z" && !has_z_unstable_option { if opt.name != "Z" && !has_z_unstable_option {
early_error( early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!( format!(
"the `-Z unstable-options` flag must also be passed to enable \ "the `-Z unstable-options` flag must also be passed to enable \
the flag `{}`", the flag `{}`",
opt.name opt.name
@ -2760,11 +2756,10 @@ pub mod nightly_options {
match opt.stability { match opt.stability {
OptionStability::Unstable => { OptionStability::Unstable => {
let msg = format!( let msg = format!(
"the option `{}` is only accepted on the \ "the option `{}` is only accepted on the nightly compiler",
nightly compiler",
opt.name opt.name
); );
early_error(ErrorOutputType::default(), &msg); early_error(ErrorOutputType::default(), msg);
} }
OptionStability::Stable => {} OptionStability::Stable => {}
} }

View file

@ -329,21 +329,21 @@ fn build_options<O: Default>(
match value { match value {
None => early_error( None => early_error(
error_format, error_format,
&format!( format!(
"{0} option `{1}` requires {2} ({3} {1}=<value>)", "{0} option `{1}` requires {2} ({3} {1}=<value>)",
outputname, key, type_desc, prefix outputname, key, type_desc, prefix
), ),
), ),
Some(value) => early_error( Some(value) => early_error(
error_format, error_format,
&format!( format!(
"incorrect value `{value}` for {outputname} option `{key}` - {type_desc} was expected" "incorrect value `{value}` for {outputname} option `{key}` - {type_desc} was expected"
), ),
), ),
} }
} }
} }
None => early_error(error_format, &format!("unknown {outputname} option: `{key}`")), None => early_error(error_format, format!("unknown {outputname} option: `{key}`")),
} }
} }
return op; return op;

View file

@ -289,7 +289,7 @@ impl ParseSess {
lint: &'static Lint, lint: &'static Lint,
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
node_id: NodeId, node_id: NodeId,
msg: &str, msg: impl Into<DiagnosticMessage>,
) { ) {
self.buffered_lints.with_lock(|buffered_lints| { self.buffered_lints.with_lock(|buffered_lints| {
buffered_lints.push(BufferedEarlyLint { buffered_lints.push(BufferedEarlyLint {
@ -307,7 +307,7 @@ impl ParseSess {
lint: &'static Lint, lint: &'static Lint,
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
node_id: NodeId, node_id: NodeId,
msg: &str, msg: impl Into<DiagnosticMessage>,
diagnostic: BuiltinLintDiagnostics, diagnostic: BuiltinLintDiagnostics,
) { ) {
self.buffered_lints.with_lock(|buffered_lints| { self.buffered_lints.with_lock(|buffered_lints| {

View file

@ -1386,10 +1386,10 @@ pub fn build_session(
let target_cfg = config::build_target_config(&sopts, target_override, &sysroot); let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
let host_triple = TargetTriple::from_triple(config::host_triple()); let host_triple = TargetTriple::from_triple(config::host_triple());
let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| { let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| {
early_error(sopts.error_format, &format!("Error loading host specification: {e}")) early_error(sopts.error_format, format!("Error loading host specification: {e}"))
}); });
for warning in target_warnings.warning_messages() { for warning in target_warnings.warning_messages() {
early_warn(sopts.error_format, &warning) early_warn(sopts.error_format, warning)
} }
let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
@ -1431,7 +1431,7 @@ pub fn build_session(
match profiler { match profiler {
Ok(profiler) => Some(Arc::new(profiler)), Ok(profiler) => Some(Arc::new(profiler)),
Err(e) => { Err(e) => {
early_warn(sopts.error_format, &format!("failed to create profiler: {e}")); early_warn(sopts.error_format, format!("failed to create profiler: {e}"));
None None
} }
} }
@ -1727,18 +1727,21 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed { pub fn early_error_no_abort(
output: config::ErrorOutputType,
msg: impl Into<DiagnosticMessage>,
) -> ErrorGuaranteed {
early_error_handler(output).struct_err(msg).emit() early_error_handler(output).struct_err(msg).emit()
} }
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { pub fn early_error(output: config::ErrorOutputType, msg: impl Into<DiagnosticMessage>) -> ! {
early_error_handler(output).struct_fatal(msg).emit() early_error_handler(output).struct_fatal(msg).emit()
} }
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_warn(output: config::ErrorOutputType, msg: &str) { pub fn early_warn(output: config::ErrorOutputType, msg: impl Into<DiagnosticMessage>) {
early_error_handler(output).struct_warn(msg).emit() early_error_handler(output).struct_warn(msg).emit()
} }

View file

@ -2260,7 +2260,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
obligation, poly_cache_entry, e, obligation, poly_cache_entry, e,
); );
debug!("confirm_param_env_candidate: {}", msg); debug!("confirm_param_env_candidate: {}", msg);
let err = infcx.tcx.ty_error_with_message(obligation.cause.span, &msg); let err = infcx.tcx.ty_error_with_message(obligation.cause.span, msg);
Progress { term: err.into(), obligations: vec![] } Progress { term: err.into(), obligations: vec![] }
} }
} }

View file

@ -773,7 +773,7 @@ impl<'tcx> ExtraInfo<'tcx> {
ExtraInfo { def_id, sp, tcx } ExtraInfo { def_id, sp, tcx }
} }
fn error_invalid_codeblock_attr(&self, msg: &str, help: &str) { fn error_invalid_codeblock_attr(&self, msg: String, help: &str) {
if let Some(def_id) = self.def_id.as_local() { if let Some(def_id) = self.def_id.as_local() {
self.tcx.struct_span_lint_hir( self.tcx.struct_span_lint_hir(
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
@ -948,7 +948,7 @@ impl LangString {
} { } {
if let Some(extra) = extra { if let Some(extra) = extra {
extra.error_invalid_codeblock_attr( extra.error_invalid_codeblock_attr(
&format!("unknown attribute `{}`. Did you mean `{}`?", x, flag), format!("unknown attribute `{}`. Did you mean `{}`?", x, flag),
help, help,
); );
} }

View file

@ -192,11 +192,11 @@ fn init_logging() {
Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(), Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
Ok(value) => early_error( Ok(value) => early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!("invalid log color value '{}': expected one of always, never, or auto", value), format!("invalid log color value '{}': expected one of always, never, or auto", value),
), ),
Err(VarError::NotUnicode(value)) => early_error( Err(VarError::NotUnicode(value)) => early_error(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!( format!(
"invalid log color value '{}': expected one of always, never, or auto", "invalid log color value '{}': expected one of always, never, or auto",
value.to_string_lossy() value.to_string_lossy()
), ),
@ -228,7 +228,7 @@ fn get_args() -> Option<Vec<String>> {
.map_err(|arg| { .map_err(|arg| {
early_warn( early_warn(
ErrorOutputType::default(), ErrorOutputType::default(),
&format!("Argument {} is not valid Unicode: {:?}", i, arg), format!("Argument {} is not valid Unicode: {:?}", i, arg),
); );
}) })
.ok() .ok()
@ -721,7 +721,7 @@ fn main_args(at_args: &[String]) -> MainResult {
let matches = match options.parse(&args[1..]) { let matches = match options.parse(&args[1..]) {
Ok(m) => m, Ok(m) => m,
Err(err) => { Err(err) => {
early_error(ErrorOutputType::default(), &err.to_string()); early_error(ErrorOutputType::default(), err.to_string());
} }
}; };

View file

@ -8,7 +8,7 @@ use rustc_data_structures::{
fx::{FxHashMap, FxHashSet}, fx::{FxHashMap, FxHashSet},
intern::Interned, intern::Interned,
}; };
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, Diagnostic, DiagnosticMessage};
use rustc_hir::def::Namespace::*; use rustc_hir::def::Namespace::*;
use rustc_hir::def::{DefKind, Namespace, PerNS}; use rustc_hir::def::{DefKind, Namespace, PerNS};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
@ -24,6 +24,7 @@ use rustc_span::BytePos;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt::Display;
use std::mem; use std::mem;
use std::ops::Range; use std::ops::Range;
@ -841,7 +842,7 @@ impl PreprocessingError {
match self { match self {
PreprocessingError::MultipleAnchors => report_multiple_anchors(cx, diag_info), PreprocessingError::MultipleAnchors => report_multiple_anchors(cx, diag_info),
PreprocessingError::Disambiguator(range, msg) => { PreprocessingError::Disambiguator(range, msg) => {
disambiguator_error(cx, diag_info, range.clone(), msg) disambiguator_error(cx, diag_info, range.clone(), msg.as_str())
} }
PreprocessingError::MalformedGenerics(err, path_str) => { PreprocessingError::MalformedGenerics(err, path_str) => {
report_malformed_generics(cx, diag_info, *err, path_str) report_malformed_generics(cx, diag_info, *err, path_str)
@ -1185,7 +1186,7 @@ impl LinkCollector<'_, '_> {
} }
suggest_disambiguator(resolved, diag, path_str, &ori_link.link, sp); suggest_disambiguator(resolved, diag, path_str, &ori_link.link, sp);
}; };
report_diagnostic(self.cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, diag_info, callback); report_diagnostic(self.cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, diag_info, callback);
} }
fn report_rawptr_assoc_feature_gate(&self, dox: &str, ori_link: &Range<usize>, item: &Item) { fn report_rawptr_assoc_feature_gate(&self, dox: &str, ori_link: &Range<usize>, item: &Item) {
@ -1581,7 +1582,7 @@ impl Suggestion {
fn report_diagnostic( fn report_diagnostic(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
lint: &'static Lint, lint: &'static Lint,
msg: &str, msg: impl Into<DiagnosticMessage> + Display,
DiagnosticInfo { item, ori_link: _, dox, link_range }: &DiagnosticInfo<'_>, DiagnosticInfo { item, ori_link: _, dox, link_range }: &DiagnosticInfo<'_>,
decorate: impl FnOnce(&mut Diagnostic, Option<rustc_span::Span>), decorate: impl FnOnce(&mut Diagnostic, Option<rustc_span::Span>),
) { ) {
@ -1649,7 +1650,7 @@ fn resolution_failure(
report_diagnostic( report_diagnostic(
tcx, tcx,
BROKEN_INTRA_DOC_LINKS, BROKEN_INTRA_DOC_LINKS,
&format!("unresolved link to `{}`", path_str), format!("unresolved link to `{}`", path_str),
&diag_info, &diag_info,
|diag, sp| { |diag, sp| {
let item = |res: Res| format!("the {} `{}`", res.descr(), res.name(tcx),); let item = |res: Res| format!("the {} `{}`", res.descr(), res.name(tcx),);
@ -1865,20 +1866,20 @@ fn resolution_failure(
fn report_multiple_anchors(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>) { fn report_multiple_anchors(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>) {
let msg = format!("`{}` contains multiple anchors", diag_info.ori_link); let msg = format!("`{}` contains multiple anchors", diag_info.ori_link);
anchor_failure(cx, diag_info, &msg, 1) anchor_failure(cx, diag_info, msg, 1)
} }
fn report_anchor_conflict(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, def_id: DefId) { fn report_anchor_conflict(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, def_id: DefId) {
let (link, kind) = (diag_info.ori_link, Res::from_def_id(cx.tcx, def_id).descr()); let (link, kind) = (diag_info.ori_link, Res::from_def_id(cx.tcx, def_id).descr());
let msg = format!("`{link}` contains an anchor, but links to {kind}s are already anchored"); let msg = format!("`{link}` contains an anchor, but links to {kind}s are already anchored");
anchor_failure(cx, diag_info, &msg, 0) anchor_failure(cx, diag_info, msg, 0)
} }
/// Report an anchor failure. /// Report an anchor failure.
fn anchor_failure( fn anchor_failure(
cx: &DocContext<'_>, cx: &DocContext<'_>,
diag_info: DiagnosticInfo<'_>, diag_info: DiagnosticInfo<'_>,
msg: &str, msg: String,
anchor_idx: usize, anchor_idx: usize,
) { ) {
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, sp| { report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, sp| {
@ -1898,7 +1899,7 @@ fn disambiguator_error(
cx: &DocContext<'_>, cx: &DocContext<'_>,
mut diag_info: DiagnosticInfo<'_>, mut diag_info: DiagnosticInfo<'_>,
disambiguator_range: Range<usize>, disambiguator_range: Range<usize>,
msg: &str, msg: impl Into<DiagnosticMessage> + Display,
) { ) {
diag_info.link_range = disambiguator_range; diag_info.link_range = disambiguator_range;
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| { report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| {
@ -1919,7 +1920,7 @@ fn report_malformed_generics(
report_diagnostic( report_diagnostic(
cx.tcx, cx.tcx,
BROKEN_INTRA_DOC_LINKS, BROKEN_INTRA_DOC_LINKS,
&format!("unresolved link to `{}`", path_str), format!("unresolved link to `{}`", path_str),
&diag_info, &diag_info,
|diag, sp| { |diag, sp| {
let note = match err { let note = match err {
@ -1994,7 +1995,7 @@ fn ambiguity_error(
} }
} }
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, diag_info, |diag, sp| { report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, diag_info, |diag, sp| {
if let Some(sp) = sp { if let Some(sp) = sp {
diag.span_label(sp, "ambiguous link"); diag.span_label(sp, "ambiguous link");
} else { } else {
@ -2046,7 +2047,7 @@ fn privacy_error(cx: &DocContext<'_>, diag_info: &DiagnosticInfo<'_>, path_str:
let msg = let msg =
format!("public documentation for `{}` links to private item `{}`", item_name, path_str); format!("public documentation for `{}` links to private item `{}`", item_name, path_str);
report_diagnostic(cx.tcx, PRIVATE_INTRA_DOC_LINKS, &msg, diag_info, |diag, sp| { report_diagnostic(cx.tcx, PRIVATE_INTRA_DOC_LINKS, msg, diag_info, |diag, sp| {
if let Some(sp) = sp { if let Some(sp) = sp {
diag.span_label(sp, "this item is private"); diag.span_label(sp, "this item is private");
} }