Use Cow
in {D,Subd}iagnosticMessage
.
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment: ``` // FIXME(davidtwco): can a `Cow<'static, str>` be used here? ``` This commit answers that question in the affirmative. It's not the most compelling change ever, but it might be worth merging. This requires changing the `impl<'a> From<&'a str>` impls to `impl From<&'static str>`, which involves a bunch of knock-on changes that require/result in call sites being a little more precise about exactly what kind of string they use to create errors, and not just `&str`. This will result in fewer unnecessary allocations, though this will not have any notable perf effects given that these are error paths. Note that I was lazy within Clippy, using `to_string` in a few places to preserve the existing string imprecision. I could have used `impl Into<{D,Subd}iagnosticMessage>` in various places as is done in the compiler, but that would have required changes to *many* call sites (mostly changing `&format("...")` to `format!("...")`) which didn't seem worthwhile.
This commit is contained in:
parent
1c53407e8c
commit
781111ef35
45 changed files with 308 additions and 287 deletions
|
@ -42,6 +42,7 @@ use rustc_session::Limit;
|
|||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{ExpnKind, Span, DUMMY_SP};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
use std::ops::ControlFlow;
|
||||
|
@ -1602,7 +1603,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}),
|
||||
) => Some((
|
||||
ty.span,
|
||||
with_forced_trimmed_paths!(format!(
|
||||
with_forced_trimmed_paths!(Cow::from(format!(
|
||||
"type mismatch resolving `{}`",
|
||||
self.resolve_vars_if_possible(predicate)
|
||||
.print(FmtPrinter::new_with_limit(
|
||||
|
@ -1612,7 +1613,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
))
|
||||
.unwrap()
|
||||
.into_buffer()
|
||||
)),
|
||||
))),
|
||||
)),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ use rustc_span::def_id::LocalDefId;
|
|||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi;
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
use std::ops::Deref;
|
||||
|
||||
|
@ -186,7 +187,12 @@ pub trait TypeErrCtxtExt<'tcx> {
|
|||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<Symbol>;
|
||||
fn get_closure_name(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
err: &mut Diagnostic,
|
||||
msg: Cow<'static, str>,
|
||||
) -> Option<Symbol>;
|
||||
|
||||
fn suggest_fn_call(
|
||||
&self,
|
||||
|
@ -857,7 +863,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
/// Given a closure's `DefId`, return the given name of the closure.
|
||||
///
|
||||
/// This doesn't account for reassignments, but it's only used for suggestions.
|
||||
fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<Symbol> {
|
||||
fn get_closure_name(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
err: &mut Diagnostic,
|
||||
msg: Cow<'static, str>,
|
||||
) -> Option<Symbol> {
|
||||
let get_name = |err: &mut Diagnostic, kind: &hir::PatKind<'_>| -> Option<Symbol> {
|
||||
// Get the local name of this closure. This can be inaccurate because
|
||||
// of the possibility of reassignment, but this should be good enough.
|
||||
|
@ -934,17 +945,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let msg = match def_id_or_name {
|
||||
DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
|
||||
DefKind::Ctor(CtorOf::Struct, _) => {
|
||||
"use parentheses to construct this tuple struct".to_string()
|
||||
Cow::from("use parentheses to construct this tuple struct")
|
||||
}
|
||||
DefKind::Ctor(CtorOf::Variant, _) => {
|
||||
"use parentheses to construct this tuple variant".to_string()
|
||||
Cow::from("use parentheses to construct this tuple variant")
|
||||
}
|
||||
kind => format!(
|
||||
kind => Cow::from(format!(
|
||||
"use parentheses to call this {}",
|
||||
self.tcx.def_kind_descr(kind, def_id)
|
||||
),
|
||||
)),
|
||||
},
|
||||
DefIdOrName::Name(name) => format!("use parentheses to call this {name}"),
|
||||
DefIdOrName::Name(name) => Cow::from(format!("use parentheses to call this {name}")),
|
||||
};
|
||||
|
||||
let args = inputs
|
||||
|
@ -979,7 +990,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
..
|
||||
})) => {
|
||||
err.span_label(*fn_decl_span, "consider calling this closure");
|
||||
let Some(name) = self.get_closure_name(def_id, err, &msg) else {
|
||||
let Some(name) = self.get_closure_name(def_id, err, msg.clone()) else {
|
||||
return false;
|
||||
};
|
||||
name.to_string()
|
||||
|
@ -1341,7 +1352,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err.note(msg);
|
||||
} else {
|
||||
err.message =
|
||||
vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)];
|
||||
vec![(rustc_errors::DiagnosticMessage::from(msg), Style::NoStyle)];
|
||||
}
|
||||
err.span_label(
|
||||
span,
|
||||
|
@ -2958,7 +2969,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
for ty in bound_tys.skip_binder() {
|
||||
with_forced_trimmed_paths!(write!(msg, "`{}`, ", ty).unwrap());
|
||||
}
|
||||
err.note(msg.trim_end_matches(", "))
|
||||
err.note(msg.trim_end_matches(", ").to_string())
|
||||
}
|
||||
ty::GeneratorWitnessMIR(def_id, substs) => {
|
||||
use std::fmt::Write;
|
||||
|
@ -2972,7 +2983,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let ty = bty.subst(tcx, substs);
|
||||
write!(msg, "`{}`, ", ty).unwrap();
|
||||
}
|
||||
err.note(msg.trim_end_matches(", "))
|
||||
err.note(msg.trim_end_matches(", ").to_string())
|
||||
}
|
||||
ty::Generator(def_id, _, _) => {
|
||||
let sp = self.tcx.def_span(def_id);
|
||||
|
|
|
@ -41,7 +41,12 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> {
|
|||
|
||||
/// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate
|
||||
/// trait aliases.
|
||||
pub fn label_with_exp_info(&self, diag: &mut Diagnostic, top_label: &str, use_desc: &str) {
|
||||
pub fn label_with_exp_info(
|
||||
&self,
|
||||
diag: &mut Diagnostic,
|
||||
top_label: &'static str,
|
||||
use_desc: &str,
|
||||
) {
|
||||
diag.span_label(self.top().1, top_label);
|
||||
if self.path.len() > 1 {
|
||||
for (_, sp) in self.path.iter().rev().skip(1).take(self.path.len() - 2) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue