1
Fork 0

Restrict From<S> for {D,Subd}iagnosticMessage.

Currently a `{D,Subd}iagnosticMessage` can be created from any type that
impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static,
str>`, which are reasonable. It also includes `&String`, which is pretty
weird, and results in many places making unnecessary allocations for
patterns like this:
```
self.fatal(&format!(...))
```
This creates a string with `format!`, takes a reference, passes the
reference to `fatal`, which does an `into()`, which clones the
reference, doing a second allocation. Two allocations for a single
string, bleh.

This commit changes the `From` impls so that you can only create a
`{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static,
str>`. This requires changing all the places that currently create one
from a `&String`. Most of these are of the `&format!(...)` form
described above; each one removes an unnecessary static `&`, plus an
allocation when executed. There are also a few places where the existing
use of `&String` was more reasonable; these now just use `clone()` at
the call site.

As well as making the code nicer and more efficient, this is a step
towards possibly using `Cow<'static, str>` in
`{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing
the `From<&'a str>` impls to `From<&'static str>`, which is doable, but
I'm not yet sure if it's worthwhile.
This commit is contained in:
Nicholas Nethercote 2023-04-20 13:26:58 +10:00
parent a368898de7
commit 6b62f37402
177 changed files with 791 additions and 787 deletions

View file

@ -271,7 +271,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
let underscores = vec!["_"; expected_args.len()].join(", ");
err.span_suggestion_verbose(
closure_arg_span.unwrap_or(found_span),
&format!(
format!(
"consider changing the closure to take and ignore the expected argument{}",
pluralize!(expected_args.len())
),
@ -575,7 +575,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
Limit(0) => Limit(2),
limit => limit * 2,
};
err.help(&format!(
err.help(format!(
"consider increasing the recursion limit by adding a \
`#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
suggested_limit,
@ -737,7 +737,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) {
err.span_label(
ret_span,
&format!(
format!(
"expected `{}` because of this",
trait_ref.skip_binder().self_ty()
),
@ -780,7 +780,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.emit();
return;
}
if let Some(ref s) = label {
if let Some(s) = label {
// If it has a custom `#[rustc_on_unimplemented]`
// error message, let's display it as the label!
err.span_label(span, s);
@ -788,7 +788,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// When the self type is a type param We don't need to "the trait
// `std::marker::Sized` is not implemented for `T`" as we will point
// at the type param with a label to suggest constraining it.
err.help(&explanation);
err.help(explanation);
}
} else if let Some(custom_explanation) = safe_transmute_explanation {
err.span_label(span, custom_explanation);
@ -811,13 +811,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
if let Some((msg, span)) = type_def {
err.span_label(span, &msg);
err.span_label(span, msg);
}
if let Some(ref s) = note {
if let Some(s) = note {
// If it has a custom `#[rustc_on_unimplemented]` note, let's display it
err.note(s.as_str());
err.note(s);
}
if let Some(ref s) = parent_label {
if let Some(s) = parent_label {
let body = obligation.cause.body_id;
err.span_label(tcx.def_span(body), s);
}
@ -1028,7 +1028,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// which bounds actually failed to hold.
self.tcx.sess.struct_span_err(
span,
&format!("the type `{}` is not well-formed", ty),
format!("the type `{}` is not well-formed", ty),
)
}
}
@ -1071,7 +1071,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
let mut diag = self.tcx.sess.struct_span_err(
span,
&format!("the constant `{}` is not of type `{}`", ct, ty),
format!("the constant `{}` is not of type `{}`", ct, ty),
);
self.note_type_err(
&mut diag,
@ -1835,7 +1835,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
candidates.sort();
candidates.dedup();
let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
err.help(&format!(
err.help(format!(
"the following {other}types implement trait `{}`:{}{}",
trait_ref.print_only_trait_path(),
candidates[..end].join(""),
@ -2026,7 +2026,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
"perhaps two different versions of crate `{}` are being used?",
trait_crate
);
err.note(&crate_msg);
err.note(crate_msg);
suggested = true;
}
suggested
@ -2158,7 +2158,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.cancel();
return;
}
err.note(&format!("cannot satisfy `{}`", predicate));
err.note(format!("cannot satisfy `{}`", predicate));
let impl_candidates = self.find_similar_impl_candidates(
predicate.to_opt_poly_trait_pred().unwrap(),
);
@ -2178,7 +2178,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.cancel();
return;
}
err.note(&format!("cannot satisfy `{}`", predicate));
err.note(format!("cannot satisfy `{}`", predicate));
}
}
@ -2223,9 +2223,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.cancel();
err = self.tcx.sess.struct_span_err_with_code(
span,
&format!(
format!(
"cannot {verb} associated {noun} on trait without specifying the corresponding `impl` type",
),
),
rustc_errors::error_code!(E0790),
);
@ -2332,7 +2332,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ErrorCode::E0284,
true,
);
err.note(&format!("cannot satisfy `{}`", predicate));
err.note(format!("cannot satisfy `{}`", predicate));
err
} else {
// If we can't find a substitution, just print a generic error
@ -2343,7 +2343,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
"type annotations needed: cannot satisfy `{}`",
predicate,
);
err.span_label(span, &format!("cannot satisfy `{}`", predicate));
err.span_label(span, format!("cannot satisfy `{}`", predicate));
err
}
}
@ -2371,7 +2371,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
"type annotations needed: cannot satisfy `{}`",
predicate,
);
err.span_label(span, &format!("cannot satisfy `{}`", predicate));
err.span_label(span, format!("cannot satisfy `{}`", predicate));
err
}
}
@ -2386,7 +2386,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
"type annotations needed: cannot satisfy `{}`",
predicate,
);
err.span_label(span, &format!("cannot satisfy `{}`", predicate));
err.span_label(span, format!("cannot satisfy `{}`", predicate));
err
}
};
@ -2459,13 +2459,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
match (spans.len(), crates.len(), crate_names.len()) {
(0, 0, 0) => {
err.note(&format!("cannot satisfy `{}`", predicate));
err.note(format!("cannot satisfy `{}`", predicate));
}
(0, _, 1) => {
err.note(&format!("{} in the `{}` crate{}", msg, crates[0], post,));
err.note(format!("{} in the `{}` crate{}", msg, crates[0], post,));
}
(0, _, _) => {
err.note(&format!(
err.note(format!(
"{} in the following crates: {}{}",
msg,
crate_names.join(", "),
@ -2474,19 +2474,17 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
(_, 0, 0) => {
let span: MultiSpan = spans.into();
err.span_note(span, &msg);
err.span_note(span, msg);
}
(_, 1, 1) => {
let span: MultiSpan = spans.into();
err.span_note(span, &msg);
err.note(
&format!("and another `impl` found in the `{}` crate{}", crates[0], post,),
);
err.span_note(span, msg);
err.note(format!("and another `impl` found in the `{}` crate{}", crates[0], post,));
}
_ => {
let span: MultiSpan = spans.into();
err.span_note(span, &msg);
err.note(&format!(
err.span_note(span, msg);
err.note(format!(
"and more `impl`s found in the following crates: {}{}",
crate_names.join(", "),
post,
@ -2657,7 +2655,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
err.span_help(
multispan,
&format!(
format!(
"you could relax the implicit `Sized` bound on `{T}` if it were \
used through indirection like `&{T}` or `Box<{T}>`",
T = param.name.ident(),
@ -2882,7 +2880,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
.fn_trait_kind_from_def_id(trait_ref.def_id())
.expect("expected to map DefId to ClosureKind");
if !implemented_kind.extends(selected_kind) {
err.note(&format!(
err.note(format!(
"`{}` implements `{}`, but it must implement `{}`, which is more general",
trait_ref.skip_binder().self_ty(),
implemented_kind,
@ -2899,7 +2897,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if expected.len() != given.len() {
// Note number of types that were expected and given
err.note(
&format!(
format!(
"expected a closure taking {} argument{}, but one taking {} argument{} was given",
given.len(),
pluralize!(given.len()),
@ -2942,7 +2940,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
unsatisfied_const = UnsatisfiedConst(true);
err.span_note(
span,
&format!(
format!(
"the trait `{}` is implemented for `{}`, \
but that implementation is not `const`",
non_const_predicate.print_modifiers_and_trait_path(),
@ -3171,7 +3169,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let mut err = self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
let const_span = self.tcx.def_span(uv.def);
match self.tcx.sess.source_map().span_to_snippet(const_span) {
Ok(snippet) => err.help(&format!(
Ok(snippet) => err.help(format!(
"try adding a `where` bound using this expression: `where [(); {}]:`",
snippet
)),

View file

@ -515,7 +515,7 @@ fn suggest_restriction<'tcx>(
err.span_suggestion_verbose(
sp,
&format!("consider further restricting {}", msg),
format!("consider further restricting {}", msg),
suggestion,
Applicability::MachineApplicable,
);
@ -964,7 +964,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// a more general note.
err.span_suggestion_verbose(
obligation.cause.span.shrink_to_hi(),
&msg,
msg,
format!("({args})"),
Applicability::HasPlaceholders,
);
@ -994,7 +994,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
_ => return false,
};
err.help(&format!("{msg}: `{name}({args})`"));
err.help(format!("{msg}: `{name}({args})`"));
}
true
}
@ -1334,7 +1334,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let msg = format!("the trait bound `{}` is not satisfied", old_pred);
if has_custom_message {
err.note(&msg);
err.note(msg);
} else {
err.message =
vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)];
@ -1358,7 +1358,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} else {
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
let sugg_prefix = format!("&{}", if is_mut { "mut " } else { "" });
let sugg_msg = &format!(
let sugg_msg = format!(
"consider{} borrowing here",
if is_mut { " mutably" } else { "" }
);
@ -1452,7 +1452,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.span_suggestion(
obligation.cause.span.shrink_to_lo(),
&format!(
format!(
"consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`"
),
"&",
@ -1505,7 +1505,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
};
err.multipart_suggestion_verbose(
&msg,
msg,
suggestions,
Applicability::MachineApplicable,
);
@ -1617,7 +1617,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) =
obligation.predicate.kind().skip_binder()
{
err.span_label(*span, &format!("this call returns `{}`", pred.self_ty()));
err.span_label(*span, format!("this call returns `{}`", pred.self_ty()));
}
if let Some(typeck_results) = &self.typeck_results
&& let ty = typeck_results.expr_ty_adjusted(base)
@ -1632,14 +1632,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if vis_span.is_empty() {
err.span_suggestion_verbose(
span.shrink_to_lo(),
&msg,
msg,
"async ",
Applicability::MaybeIncorrect,
);
} else {
err.span_suggestion_verbose(
vis_span.shrink_to_hi(),
&msg,
msg,
" async",
Applicability::MaybeIncorrect,
);
@ -1717,7 +1717,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
Applicability::MachineApplicable,
);
} else {
err.note(&format!(
err.note(format!(
"`{}` is implemented for `{:?}`, but not for `{:?}`",
trait_pred.print_modifiers_and_trait_path(),
suggested_ty,
@ -1754,7 +1754,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
err.span_label(
expr.span,
&format!(
format!(
"this expression has type `{}`, which implements `{}`",
ty,
trait_pred.print_modifiers_and_trait_path()
@ -1946,7 +1946,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Suggest `-> impl Trait`.
err.span_suggestion(
ret_ty.span,
&format!(
format!(
"use `impl {1}` as the return type, as all return paths are of type `{}`, \
which implements `{1}`",
last_ty, trait_obj,
@ -1981,13 +1981,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} else {
// This is currently not possible to trigger because E0038 takes precedence, but
// leave it in for completeness in case anything changes in an earlier stage.
err.note(&format!(
err.note(format!(
"if trait `{}` were object-safe, you could return a trait object",
trait_obj,
));
}
err.note(trait_obj_msg);
err.note(&format!(
err.note(format!(
"if all the returned values were of the same type you could use `impl {}` as the \
return type",
trait_obj,
@ -2027,7 +2027,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} else {
err.span_label(
expr.span,
&format!("this returned value is of type `{}`", ty),
format!("this returned value is of type `{}`", ty),
);
}
}
@ -2177,7 +2177,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) {
if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) {
if let ty::AssocKind::Const | ty::AssocKind::Type = assoc_item.kind {
err.note(&format!(
err.note(format!(
"{}s cannot be accessed directly on a `trait`, they can only be \
accessed through a specific `impl`",
self.tcx.def_kind_descr(assoc_item.kind.as_def_kind(), item_def_id)
@ -2607,7 +2607,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
err.span_note(
span,
&format!(
format!(
"{} {} as this value is used across {}",
future_or_generator, trait_explanation, an_await_or_yield
),
@ -2628,7 +2628,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
err.span_note(
span,
&format!(
format!(
"future {not_trait} as it awaits another future which {not_trait}",
not_trait = trait_explanation
),
@ -2730,7 +2730,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let mut span = MultiSpan::from_span(upvar_span);
span.push_span_label(upvar_span, span_label);
err.span_note(span, &span_note);
err.span_note(span, span_note);
}
}
@ -2794,15 +2794,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.note("only the last element of a tuple may have a dynamically sized type");
}
ObligationCauseCode::ProjectionWf(data) => {
err.note(&format!("required so that the projection `{data}` is well-formed"));
err.note(format!("required so that the projection `{data}` is well-formed"));
}
ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
err.note(&format!(
err.note(format!(
"required so that reference `{ref_ty}` does not outlive its referent"
));
}
ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
err.note(&format!(
err.note(format!(
"required so that the lifetime bound of `{}` for `{}` is satisfied",
region, object_ty,
));
@ -2838,9 +2838,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if span.is_visible(sm) {
let msg = format!("required by this bound in `{short_item_name}`");
multispan.push_span_label(span, msg);
err.span_note(multispan, &descr);
err.span_note(multispan, descr);
} else {
err.span_note(tcx.def_span(item_def_id), &descr);
err.span_note(tcx.def_span(item_def_id), descr);
}
}
ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => {
@ -2848,24 +2848,24 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty));
let (object_ty, object_file) =
self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty));
err.note(&with_forced_trimmed_paths!(format!(
err.note(with_forced_trimmed_paths!(format!(
"required for the cast from `{concrete_ty}` to the object type `{object_ty}`",
)));
if let Some(file) = concrete_file {
err.note(&format!(
err.note(format!(
"the full name for the casted type has been written to '{}'",
file.display(),
));
}
if let Some(file) = object_file {
err.note(&format!(
err.note(format!(
"the full name for the object type has been written to '{}'",
file.display(),
));
}
}
ObligationCauseCode::Coercion { source: _, target } => {
err.note(&format!("required by cast to type `{}`", self.ty_to_string(target)));
err.note(format!("required by cast to type `{}`", self.ty_to_string(target)));
}
ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
err.note(
@ -3068,8 +3068,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
));
match ty.kind() {
ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) {
Some(ident) => err.span_note(ident.span, &msg),
None => err.note(&msg),
Some(ident) => err.span_note(ident.span, msg),
None => err.note(msg),
},
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
// If the previous type is async fn, this is the future generated by the body of an async function.
@ -3090,7 +3090,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
break 'print;
}
err.span_note(self.tcx.def_span(def_id), &msg)
err.span_note(self.tcx.def_span(def_id), msg)
}
ty::GeneratorWitness(bound_tys) => {
use std::fmt::Write;
@ -3126,7 +3126,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let kind = tcx.generator_kind(def_id).unwrap().descr();
err.span_note(
sp,
with_forced_trimmed_paths!(&format!(
with_forced_trimmed_paths!(format!(
"required because it's used within this {kind}",
)),
)
@ -3136,7 +3136,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
"required because it's used within this closure",
),
ty::Str => err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes"),
_ => err.note(&msg),
_ => err.note(msg),
};
}
}
@ -3190,7 +3190,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// FIXME: we should do something else so that it works even on crate foreign
// auto traits.
is_auto_trait = matches!(is_auto, hir::IsAuto::Yes);
err.span_note(ident.span, &msg);
err.span_note(ident.span, msg);
}
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
@ -3219,15 +3219,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
"unsatisfied trait bound introduced here",
);
}
err.span_note(spans, &msg);
err.span_note(spans, msg);
}
_ => {
err.note(&msg);
err.note(msg);
}
};
if let Some(file) = file {
err.note(&format!(
err.note(format!(
"the full type name has been written to '{}'",
file.display(),
));
@ -3267,19 +3267,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
parent_trait_pred = child_trait_pred;
}
if count > 0 {
err.note(&format!(
err.note(format!(
"{} redundant requirement{} hidden",
count,
pluralize!(count)
));
let (self_ty, file) =
self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
err.note(&format!(
err.note(format!(
"required for `{self_ty}` to implement `{}`",
parent_trait_pred.print_modifiers_and_trait_path()
));
if let Some(file) = file {
err.note(&format!(
err.note(format!(
"the full type name has been written to '{}'",
file.display(),
));
@ -3360,7 +3360,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
assoc_span.push_span_label(ident.span, "in this trait");
}
err.span_note(assoc_span, &msg);
err.span_note(assoc_span, msg);
}
ObligationCauseCode::TrivialBound => {
err.help("see issue #48214");
@ -3516,7 +3516,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if can_derive {
err.span_suggestion_verbose(
self.tcx.def_span(adt.did()).shrink_to_lo(),
&format!(
format!(
"consider annotating `{}` with `#[derive({})]`",
trait_pred.skip_binder().self_ty(),
diagnostic_name,
@ -3903,7 +3903,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
.map(|trait_ref| trait_ref.trait_ref.self_ty())
.find(|t| is_slice(*t))
{
let msg = &format!("convert the array to a `{}` slice instead", slice_ty);
let msg = format!("convert the array to a `{}` slice instead", slice_ty);
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
let mut suggestions = vec![];
@ -4124,7 +4124,7 @@ fn suggest_trait_object_return_type_alternatives(
) {
err.span_suggestion(
ret_ty,
&format!(
format!(
"use `impl {}` as the return type if all return paths have the same type but you \
want to expose only the trait in the signature",
trait_obj,
@ -4134,7 +4134,7 @@ fn suggest_trait_object_return_type_alternatives(
);
if is_object_safe {
err.multipart_suggestion(
&format!(
format!(
"use a boxed trait object if all return paths implement trait `{}`",
trait_obj,
),

View file

@ -525,7 +525,7 @@ fn virtual_call_violation_for_method<'tcx>(
// #78372
tcx.sess.delay_span_bug(
tcx.def_span(method.def_id),
&format!("error: {}\n while computing layout for type {:?}", err, ty),
format!("error: {}\n while computing layout for type {:?}", err, ty),
);
None
}
@ -541,7 +541,7 @@ fn virtual_call_violation_for_method<'tcx>(
abi => {
tcx.sess.delay_span_bug(
tcx.def_span(method.def_id),
&format!(
format!(
"receiver when `Self = ()` should have a Scalar ABI; found {:?}",
abi
),
@ -560,7 +560,7 @@ fn virtual_call_violation_for_method<'tcx>(
abi => {
tcx.sess.delay_span_bug(
tcx.def_span(method.def_id),
&format!(
format!(
"receiver when `Self = {}` should have a ScalarPair ABI; found {:?}",
trait_object_ty, abi
),

View file

@ -1749,7 +1749,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// These traits have no associated types.
selcx.tcx().sess.delay_span_bug(
obligation.cause.span,
&format!("Cannot project an associated type from `{:?}`", impl_source),
format!("Cannot project an associated type from `{:?}`", impl_source),
);
return Err(());
}

View file

@ -79,7 +79,7 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
if !errors.is_empty() {
infcx.tcx.sess.diagnostic().delay_span_bug(
DUMMY_SP,
&format!("errors selecting obligation during MIR typeck: {:?}", errors),
format!("errors selecting obligation during MIR typeck: {:?}", errors),
);
}

View file

@ -67,7 +67,7 @@ impl IntercrateAmbiguityCause {
/// Emits notes when the overlap is caused by complex intercrate ambiguities.
/// See #23980 for details.
pub fn add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic) {
err.note(&self.intercrate_ambiguity_hint());
err.note(self.intercrate_ambiguity_hint());
}
pub fn intercrate_ambiguity_hint(&self) -> String {
@ -2449,7 +2449,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// for a variable being generalized...
let guar = self.infcx.tcx.sess.delay_span_bug(
obligation.cause.span,
&format!(
format!(
"Impl {:?} was matchable against {:?} but now is not",
impl_def_id, obligation
),

View file

@ -373,7 +373,7 @@ fn report_conflicting_impls<'tcx>(
}
None => format!("conflicting implementation in crate `{}`", cname),
};
err.note(&msg);
err.note(msg);
}
}