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

View file

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

View file

@ -71,7 +71,7 @@ macro_rules! span_mirbug {
$crate::type_check::mirbug(
$context.tcx(),
$context.last_span,
&format!(
format!(
"broken MIR in {:?} ({:?}): {}",
$context.body().source.def_id(),
$elem,
@ -274,7 +274,7 @@ fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
}
#[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
// the fact that we check rvalue sized predicates here. So use `delay_span_bug`
// 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() {
let err = parser.errors.remove(0);
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);
e.span_label(err_sp, err.label + " in asm template string");
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)
{
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");
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(
template_span
.from_inner(InnerSpan::new(span.start, span.end)),
&msg,
msg,
)
.emit();
None

View file

@ -145,7 +145,7 @@ fn cs_clone_simple(
}
_ => cx.span_bug(
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;
}
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(..) => {
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 {
cx.span_bug(
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);

View file

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

View file

@ -814,7 +814,7 @@ fn report_invalid_references(
};
e = ecx.struct_span_err(
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");
}

View file

@ -188,12 +188,12 @@ pub fn expand_include_str(
base::MacEager::expr(cx.expr_str(sp, interned_src))
}
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)
}
},
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)
}
}
@ -221,7 +221,7 @@ pub fn expand_include_bytes(
base::MacEager::expr(expr)
}
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)
}
}

View file

@ -227,7 +227,7 @@ pub(crate) fn write_ir_file(
// Using early_warn as no Session is available here
rustc_session::early_warn(
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),
Err(err) => rustc_session::early_error(
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"),
_ => early_error(
config.opts.error_format,
&format!(
format!(
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
matches.free[0], matches.free[1],
),
@ -527,7 +527,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
}
}
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}`?")),
_ => 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:
@ -1250,7 +1250,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
#[cfg(windows)]
if let Some(msg) = info.payload().downcast_ref::<String>() {
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;
}
};
@ -1342,7 +1342,7 @@ pub fn init_rustc_env_logger() {
/// other than `RUSTC_LOG`.
pub fn init_env_logger(env: &str) {
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| {
early_error(
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::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>(

View file

@ -24,7 +24,7 @@ fn generic_arg_mismatch_err(
arg: &GenericArg<'_>,
param: &GenericParamDef,
possible_ordering_error: bool,
help: Option<&str>,
help: Option<String>,
) -> ErrorGuaranteed {
let sess = tcx.sess;
let mut err = struct_span_err!(
@ -300,7 +300,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>(
arg,
param,
!args_iter.clone().is_sorted_by_key(|arg| arg.to_ord()),
Some(&format!(
Some(format!(
"reorder the arguments: {}: `<{}>`",
param_types_present
.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 {
return tcx.ty_error_with_message(
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
@ -205,14 +205,14 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
} else {
return tcx.ty_error_with_message(
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(
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 => {
return tcx.ty_error_with_message(
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(
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 {
return tcx.ty_error_with_message(
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(
&mut err,
&format!("a method `{field}` also exists, call it with parentheses"),
format!("a method `{field}` also exists, call it with parentheses"),
field,
expr_t,
expr,

View file

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

View file

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

View file

@ -237,7 +237,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// error has been emitted. (#64638)
self.fcx.tcx.ty_error_with_message(
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);

View file

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

View file

@ -88,7 +88,7 @@ pub fn create_session(
) {
Ok(bundle) => bundle,
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 {
let lib = unsafe { Library::new(path) }.unwrap_or_else(|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") }
.unwrap_or_else(|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
@ -320,7 +320,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
"failed to find a `codegen-backends` folder \
in the sysroot candidates:\n* {candidates}"
);
early_error(ErrorOutputType::default(), &err);
early_error(ErrorOutputType::default(), err);
});
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(),
e
);
early_error(ErrorOutputType::default(), &err);
early_error(ErrorOutputType::default(), err);
});
let mut file: Option<PathBuf> = None;
@ -359,7 +359,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
prev.display(),
path.display()
);
early_error(ErrorOutputType::default(), &err);
early_error(ErrorOutputType::default(), err);
}
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),
None => {
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,
span,
ast::CRATE_NODE_ID,
&format!(
format!(
"external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`",
name,
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
/// ensure it gets used.
#[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);
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
/// ensure it gets used.
#[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)
}
}

View file

@ -268,7 +268,7 @@ pub struct LayoutCx<'tcx, C> {
impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
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);
}

View file

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

View file

@ -186,7 +186,7 @@ fn emit_malformed_attribute(
suggestions.push(code);
}
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 {
sess.span_diagnostic
.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| {
early_error(
opts.error_format,
&format!(
format!(
"Error loading target specification: {}. \
Run `rustc --print target-list` for a list of built-in targets",
e
@ -1327,15 +1327,14 @@ pub(super) fn build_target_config(
)
});
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) {
early_error(
opts.error_format,
&format!(
"target specification was invalid: \
unrecognized target-pointer-width {}",
format!(
"target specification was invalid: unrecognized 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| {
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)
@ -1616,7 +1615,7 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
Some(arg) => early_error(
ErrorOutputType::default(),
&format!(
format!(
"argument for `--color` must be auto, \
always or never (instead was `{arg}`)"
),
@ -1691,7 +1690,7 @@ pub fn parse_json(matches: &getopts::Matches) -> JsonConfig {
"future-incompat" => json_future_incompat = true,
s => early_error(
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(
ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
&format!(
format!(
"argument for `--error-format` must be `human`, `json` or \
`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(|_| {
early_error(
ErrorOutputType::default(),
&format!(
format!(
"argument for `--edition` must be one of: \
{EDITION_NAME_LIST}. (instead was `{arg}`)"
),
@ -1782,7 +1781,7 @@ pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
} else {
format!("edition {edition} is unstable and only available with -Z unstable-options")
};
early_error(ErrorOutputType::default(), &msg)
early_error(ErrorOutputType::default(), msg)
}
edition
@ -1827,7 +1826,7 @@ fn parse_output_types(
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
early_error(
error_format,
&format!(
format!(
"unknown emission type: `{shorthand}` - expected one of: {display}",
display = OutputType::shorthands_display(),
),
@ -1866,7 +1865,7 @@ fn should_override_cgus_and_disable_thinlto(
for ot in &incompatible {
early_warn(
error_format,
&format!(
format!(
"`--emit={ot}` with `-o` incompatible with \
`-C codegen-units=N` for N > 1",
),
@ -1970,7 +1969,7 @@ fn collect_print_requests(
let prints = prints.join(", ");
early_error(
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") => {
let path = Path::new(&target);
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),
@ -2028,7 +2027,7 @@ fn parse_opt_level(
arg => {
early_error(
error_format,
&format!(
format!(
"optimization level needs to be \
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() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
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,
}
@ -2086,13 +2085,13 @@ fn parse_native_lib_kind(
} else {
", 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
}
_ => early_error(
error_format,
&format!(
format!(
"unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
),
),
@ -2127,16 +2126,13 @@ fn parse_native_lib_modifiers(
} else {
", the `-Z unstable-options` flag must also be passed to use it"
};
early_error(
error_format,
&format!("linking modifier `{modifier}` is unstable{why}"),
)
early_error(error_format, format!("linking modifier `{modifier}` is unstable{why}"))
}
};
let assign_modifier = |dst: &mut Option<bool>| {
if dst.is_some() {
let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
early_error(error_format, &msg)
early_error(error_format, msg)
} else {
*dst = Some(value);
}
@ -2173,7 +2169,7 @@ fn parse_native_lib_modifiers(
// string, like `modifiers = ""`.
_ => early_error(
error_format,
&format!(
format!(
"unknown linking modifier `{modifier}`, expected one \
of: bundle, verbatim, whole-archive, as-needed"
),
@ -2303,7 +2299,7 @@ pub fn parse_externs(
}
"nounused" => nounused_dep = 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 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 (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| {
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());
@ -2669,7 +2665,7 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
"mir-cfg" => MirCFG,
name => early_error(
efmt,
&format!(
format!(
"argument to `unpretty` must be one of `normal`, `identified`, \
`expanded`, `expanded,identified`, `expanded,hygiene`, \
`ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
@ -2747,7 +2743,7 @@ pub mod nightly_options {
if opt.name != "Z" && !has_z_unstable_option {
early_error(
ErrorOutputType::default(),
&format!(
format!(
"the `-Z unstable-options` flag must also be passed to enable \
the flag `{}`",
opt.name
@ -2760,11 +2756,10 @@ pub mod nightly_options {
match opt.stability {
OptionStability::Unstable => {
let msg = format!(
"the option `{}` is only accepted on the \
nightly compiler",
"the option `{}` is only accepted on the nightly compiler",
opt.name
);
early_error(ErrorOutputType::default(), &msg);
early_error(ErrorOutputType::default(), msg);
}
OptionStability::Stable => {}
}

View file

@ -329,21 +329,21 @@ fn build_options<O: Default>(
match value {
None => early_error(
error_format,
&format!(
format!(
"{0} option `{1}` requires {2} ({3} {1}=<value>)",
outputname, key, type_desc, prefix
),
),
Some(value) => early_error(
error_format,
&format!(
format!(
"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;

View file

@ -289,7 +289,7 @@ impl ParseSess {
lint: &'static Lint,
span: impl Into<MultiSpan>,
node_id: NodeId,
msg: &str,
msg: impl Into<DiagnosticMessage>,
) {
self.buffered_lints.with_lock(|buffered_lints| {
buffered_lints.push(BufferedEarlyLint {
@ -307,7 +307,7 @@ impl ParseSess {
lint: &'static Lint,
span: impl Into<MultiSpan>,
node_id: NodeId,
msg: &str,
msg: impl Into<DiagnosticMessage>,
diagnostic: BuiltinLintDiagnostics,
) {
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 host_triple = TargetTriple::from_triple(config::host_triple());
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() {
early_warn(sopts.error_format, &warning)
early_warn(sopts.error_format, warning)
}
let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
@ -1431,7 +1431,7 @@ pub fn build_session(
match profiler {
Ok(profiler) => Some(Arc::new(profiler)),
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
}
}
@ -1727,18 +1727,21 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
#[allow(rustc::untranslatable_diagnostic)]
#[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()
}
#[allow(rustc::untranslatable_diagnostic)]
#[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()
}
#[allow(rustc::untranslatable_diagnostic)]
#[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()
}

View file

@ -2260,7 +2260,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
obligation, poly_cache_entry, e,
);
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![] }
}
}

View file

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

View file

@ -192,11 +192,11 @@ fn init_logging() {
Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
Ok(value) => early_error(
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(
ErrorOutputType::default(),
&format!(
format!(
"invalid log color value '{}': expected one of always, never, or auto",
value.to_string_lossy()
),
@ -228,7 +228,7 @@ fn get_args() -> Option<Vec<String>> {
.map_err(|arg| {
early_warn(
ErrorOutputType::default(),
&format!("Argument {} is not valid Unicode: {:?}", i, arg),
format!("Argument {} is not valid Unicode: {:?}", i, arg),
);
})
.ok()
@ -721,7 +721,7 @@ fn main_args(at_args: &[String]) -> MainResult {
let matches = match options.parse(&args[1..]) {
Ok(m) => m,
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},
intern::Interned,
};
use rustc_errors::{Applicability, Diagnostic};
use rustc_errors::{Applicability, Diagnostic, DiagnosticMessage};
use rustc_hir::def::Namespace::*;
use rustc_hir::def::{DefKind, Namespace, PerNS};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
@ -24,6 +24,7 @@ use rustc_span::BytePos;
use smallvec::{smallvec, SmallVec};
use std::borrow::Cow;
use std::fmt::Display;
use std::mem;
use std::ops::Range;
@ -841,7 +842,7 @@ impl PreprocessingError {
match self {
PreprocessingError::MultipleAnchors => report_multiple_anchors(cx, diag_info),
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) => {
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);
};
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) {
@ -1581,7 +1582,7 @@ impl Suggestion {
fn report_diagnostic(
tcx: TyCtxt<'_>,
lint: &'static Lint,
msg: &str,
msg: impl Into<DiagnosticMessage> + Display,
DiagnosticInfo { item, ori_link: _, dox, link_range }: &DiagnosticInfo<'_>,
decorate: impl FnOnce(&mut Diagnostic, Option<rustc_span::Span>),
) {
@ -1649,7 +1650,7 @@ fn resolution_failure(
report_diagnostic(
tcx,
BROKEN_INTRA_DOC_LINKS,
&format!("unresolved link to `{}`", path_str),
format!("unresolved link to `{}`", path_str),
&diag_info,
|diag, sp| {
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<'_>) {
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) {
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");
anchor_failure(cx, diag_info, &msg, 0)
anchor_failure(cx, diag_info, msg, 0)
}
/// Report an anchor failure.
fn anchor_failure(
cx: &DocContext<'_>,
diag_info: DiagnosticInfo<'_>,
msg: &str,
msg: String,
anchor_idx: usize,
) {
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, sp| {
@ -1898,7 +1899,7 @@ fn disambiguator_error(
cx: &DocContext<'_>,
mut diag_info: DiagnosticInfo<'_>,
disambiguator_range: Range<usize>,
msg: &str,
msg: impl Into<DiagnosticMessage> + Display,
) {
diag_info.link_range = disambiguator_range;
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| {
@ -1919,7 +1920,7 @@ fn report_malformed_generics(
report_diagnostic(
cx.tcx,
BROKEN_INTRA_DOC_LINKS,
&format!("unresolved link to `{}`", path_str),
format!("unresolved link to `{}`", path_str),
&diag_info,
|diag, sp| {
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 {
diag.span_label(sp, "ambiguous link");
} else {
@ -2046,7 +2047,7 @@ fn privacy_error(cx: &DocContext<'_>, diag_info: &DiagnosticInfo<'_>, path_str:
let msg =
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 {
diag.span_label(sp, "this item is private");
}