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:
parent
a368898de7
commit
6b62f37402
177 changed files with 791 additions and 787 deletions
|
@ -1168,9 +1168,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
tcx.sess
|
||||
.struct_span_err(
|
||||
binding.span,
|
||||
&format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
||||
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
||||
)
|
||||
.span_label(binding.span, &format!("private {}", assoc_item.kind))
|
||||
.span_label(binding.span, format!("private {}", assoc_item.kind))
|
||||
.emit();
|
||||
}
|
||||
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
|
||||
|
@ -1342,11 +1342,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let expected = tcx.def_descr(assoc_item_def_id);
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
binding.span,
|
||||
&format!("expected {expected} bound, found {got}"),
|
||||
format!("expected {expected} bound, found {got}"),
|
||||
);
|
||||
err.span_note(
|
||||
tcx.def_span(assoc_item_def_id),
|
||||
&format!("{expected} defined here"),
|
||||
format!("{expected} defined here"),
|
||||
);
|
||||
|
||||
if let hir::def::DefKind::AssocConst = def_kind
|
||||
|
@ -1508,7 +1508,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
"additional use",
|
||||
);
|
||||
first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use");
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"consider creating a new trait with all of these as supertraits and using that \
|
||||
trait here instead: `trait NewTrait: {} {{}}`",
|
||||
regular_traits
|
||||
|
@ -1818,7 +1818,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
([], []) => {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a type named `Type` that implements a trait named \
|
||||
`Trait` with associated type `{name}`, you could use the \
|
||||
fully-qualified path",
|
||||
|
@ -1830,7 +1830,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
([], [trait_str]) => {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a type named `Example` that implemented `{trait_str}`, \
|
||||
you could use the fully-qualified path",
|
||||
),
|
||||
|
@ -1841,7 +1841,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
([], traits) => {
|
||||
err.span_suggestions(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a type named `Example` that implemented one of the \
|
||||
traits with associated type `{name}`, you could use the \
|
||||
fully-qualified path",
|
||||
|
@ -1856,7 +1856,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
([type_str], []) => {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a trait named `Example` with associated type `{name}` \
|
||||
implemented for `{type_str}`, you could use the fully-qualified path",
|
||||
),
|
||||
|
@ -1867,7 +1867,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
(types, []) => {
|
||||
err.span_suggestions(
|
||||
span,
|
||||
&format!(
|
||||
format!(
|
||||
"if there were a trait named `Example` with associated type `{name}` \
|
||||
implemented for one of the types, you could use the fully-qualified \
|
||||
path",
|
||||
|
@ -2033,7 +2033,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
);
|
||||
}
|
||||
} else {
|
||||
err.note(&format!(
|
||||
err.note(format!(
|
||||
"associated type `{}` could derive from `{}`",
|
||||
ty_param_name,
|
||||
bound.print_only_trait_path(),
|
||||
|
@ -2041,7 +2041,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
}
|
||||
if !where_bounds.is_empty() {
|
||||
err.help(&format!(
|
||||
err.help(format!(
|
||||
"consider introducing a new type parameter `T` and adding `where` constraints:\
|
||||
\n where\n T: {},\n{}",
|
||||
ty_param_name,
|
||||
|
@ -2109,14 +2109,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// work for the `enum`, instead of just looking if it takes *any*.
|
||||
err.span_suggestion_verbose(
|
||||
args_span,
|
||||
&format!("{type_name} doesn't have generic parameters"),
|
||||
format!("{type_name} doesn't have generic parameters"),
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return;
|
||||
}
|
||||
let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) else {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
return;
|
||||
};
|
||||
let (qself_sugg_span, is_self) = if let hir::TyKind::Path(
|
||||
|
@ -2150,12 +2150,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
kw::SelfUpper == segment.ident.name,
|
||||
),
|
||||
_ => {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
return;
|
||||
};
|
||||
let suggestion = vec![
|
||||
|
@ -2170,7 +2170,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
(args_span, String::new()),
|
||||
];
|
||||
err.multipart_suggestion_verbose(
|
||||
&msg,
|
||||
msg,
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
@ -2222,7 +2222,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let reported = if variant_resolution.is_some() {
|
||||
// Variant in type position
|
||||
let msg = format!("expected type, found variant `{}`", assoc_ident);
|
||||
tcx.sess.span_err(span, &msg)
|
||||
tcx.sess.span_err(span, msg)
|
||||
} else if qself_ty.is_enum() {
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
|
@ -2293,7 +2293,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// Assume that if it's not matched, there must be a const defined with the same name
|
||||
// but it was used in a type position.
|
||||
let msg = format!("found associated const `{assoc_ident}` when type was expected");
|
||||
let guar = tcx.sess.struct_span_err(span, &msg).emit();
|
||||
let guar = tcx.sess.struct_span_err(span, msg).emit();
|
||||
return Err(guar);
|
||||
};
|
||||
|
||||
|
@ -2313,7 +2313,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
also,
|
||||
tcx.def_kind_descr(kind, def_id)
|
||||
);
|
||||
lint.span_note(tcx.def_span(def_id), ¬e_msg);
|
||||
lint.span_note(tcx.def_span(def_id), note_msg);
|
||||
};
|
||||
|
||||
could_refer_to(DefKind::Variant, variant_def_id, "");
|
||||
|
@ -2510,9 +2510,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let msg = format!("{kind} `{name}` is private");
|
||||
let def_span = tcx.def_span(item);
|
||||
tcx.sess
|
||||
.struct_span_err_with_code(span, &msg, rustc_errors::error_code!(E0624))
|
||||
.span_label(span, &format!("private {kind}"))
|
||||
.span_label(def_span, &format!("{kind} defined here"))
|
||||
.struct_span_err_with_code(span, msg, rustc_errors::error_code!(E0624))
|
||||
.span_label(span, format!("private {kind}"))
|
||||
.span_label(def_span, format!("{kind} defined here"))
|
||||
.emit();
|
||||
}
|
||||
tcx.check_stability(item, Some(block), span, None);
|
||||
|
@ -2960,7 +2960,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self.prohibit_generics(path.segments.iter(), |err| {
|
||||
if let Some(span) = tcx.def_ident_span(def_id) {
|
||||
let name = tcx.item_name(def_id);
|
||||
err.span_note(span, &format!("type parameter `{name}` defined here"));
|
||||
err.span_note(span, format!("type parameter `{name}` defined here"));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -3021,7 +3021,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let mut span: MultiSpan = vec![t_sp].into();
|
||||
span.push_span_label(
|
||||
i_sp,
|
||||
&format!("`Self` is on type `{type_name}` in this `impl`"),
|
||||
format!("`Self` is on type `{type_name}` in this `impl`"),
|
||||
);
|
||||
let mut postfix = "";
|
||||
if generics == 0 {
|
||||
|
@ -3029,11 +3029,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
span.push_span_label(
|
||||
t_sp,
|
||||
&format!("`Self` corresponds to this type{postfix}"),
|
||||
format!("`Self` corresponds to this type{postfix}"),
|
||||
);
|
||||
err.span_note(span, &msg);
|
||||
err.span_note(span, msg);
|
||||
} else {
|
||||
err.note(&msg);
|
||||
err.note(msg);
|
||||
}
|
||||
for segment in path.segments {
|
||||
if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper {
|
||||
|
@ -3124,7 +3124,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
if let Some(args) = segment.args {
|
||||
err.span_suggestion_verbose(
|
||||
segment.ident.span.shrink_to_hi().to(args.span_ext),
|
||||
&format!("primitive type `{name}` doesn't have generic parameters"),
|
||||
format!("primitive type `{name}` doesn't have generic parameters"),
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
@ -3415,7 +3415,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
if !infer_replacements.is_empty() {
|
||||
diag.multipart_suggestion(
|
||||
&format!(
|
||||
format!(
|
||||
"try replacing `_` with the type{} in the corresponding trait method signature",
|
||||
rustc_errors::pluralize!(infer_replacements.len()),
|
||||
),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue