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
|
@ -207,11 +207,11 @@ struct MultiSugg {
|
|||
|
||||
impl MultiSugg {
|
||||
fn emit(self, err: &mut Diagnostic) {
|
||||
err.multipart_suggestion(&self.msg, self.patches, self.applicability);
|
||||
err.multipart_suggestion(self.msg, self.patches, self.applicability);
|
||||
}
|
||||
|
||||
fn emit_verbose(self, err: &mut Diagnostic) {
|
||||
err.multipart_suggestion_verbose(&self.msg, self.patches, self.applicability);
|
||||
err.multipart_suggestion_verbose(self.msg, self.patches, self.applicability);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,13 +591,13 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
self.last_unexpected_token_span = Some(self.token.span);
|
||||
// FIXME: translation requires list formatting (for `expect`)
|
||||
let mut err = self.struct_span_err(self.token.span, &msg_exp);
|
||||
let mut err = self.struct_span_err(self.token.span, msg_exp);
|
||||
|
||||
if let TokenKind::Ident(symbol, _) = &self.prev_token.kind {
|
||||
if ["def", "fun", "func", "function"].contains(&symbol.as_str()) {
|
||||
err.span_suggestion_short(
|
||||
self.prev_token.span,
|
||||
&format!("write `fn` instead of `{symbol}` to declare a function"),
|
||||
format!("write `fn` instead of `{symbol}` to declare a function"),
|
||||
"fn",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
@ -695,13 +695,13 @@ impl<'a> Parser<'a> {
|
|||
err.set_span(span);
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("remove the extra `#`{}", pluralize!(count)),
|
||||
format!("remove the extra `#`{}", pluralize!(count)),
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.span_label(
|
||||
str_span,
|
||||
&format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)),
|
||||
format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)),
|
||||
);
|
||||
true
|
||||
}
|
||||
|
@ -1360,12 +1360,12 @@ impl<'a> Parser<'a> {
|
|||
) -> PResult<'a, P<Expr>> {
|
||||
let mut err = self.struct_span_err(
|
||||
op_span,
|
||||
&format!("Rust has no {} {} operator", kind.fixity, kind.op.name()),
|
||||
format!("Rust has no {} {} operator", kind.fixity, kind.op.name()),
|
||||
);
|
||||
err.span_label(op_span, &format!("not a valid {} operator", kind.fixity));
|
||||
err.span_label(op_span, format!("not a valid {} operator", kind.fixity));
|
||||
|
||||
let help_base_case = |mut err: DiagnosticBuilder<'_, _>, base| {
|
||||
err.help(&format!("use `{}= 1` instead", kind.op.chr()));
|
||||
err.help(format!("use `{}= 1` instead", kind.op.chr()));
|
||||
err.emit();
|
||||
Ok(base)
|
||||
};
|
||||
|
@ -1554,7 +1554,7 @@ impl<'a> Parser<'a> {
|
|||
_ => this_token_str,
|
||||
},
|
||||
);
|
||||
let mut err = self.struct_span_err(sp, &msg);
|
||||
let mut err = self.struct_span_err(sp, msg);
|
||||
let label_exp = format!("expected `{token_str}`");
|
||||
let sm = self.sess.source_map();
|
||||
if !sm.is_multiline(prev_sp.until(sp)) {
|
||||
|
@ -1705,7 +1705,7 @@ impl<'a> Parser<'a> {
|
|||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err.span_suggestion(lo.shrink_to_lo(), &format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable);
|
||||
err.span_suggestion(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable);
|
||||
err.emit();
|
||||
Ok(self.mk_expr_err(lo.to(hi)))
|
||||
} else {
|
||||
|
@ -2060,7 +2060,7 @@ impl<'a> Parser<'a> {
|
|||
format!("expected expression, found {}", super::token_descr(&self.token),),
|
||||
),
|
||||
};
|
||||
let mut err = self.struct_span_err(span, &msg);
|
||||
let mut err = self.struct_span_err(span, msg);
|
||||
let sp = self.sess.source_map().start_point(self.token.span);
|
||||
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
|
||||
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
|
||||
|
@ -2131,7 +2131,7 @@ impl<'a> Parser<'a> {
|
|||
// arguments after a comma.
|
||||
let mut err = self.struct_span_err(
|
||||
self.token.span,
|
||||
&format!("expected one of `,` or `>`, found {}", super::token_descr(&self.token)),
|
||||
format!("expected one of `,` or `>`, found {}", super::token_descr(&self.token)),
|
||||
);
|
||||
err.span_label(self.token.span, "expected one of `,` or `>`");
|
||||
match self.recover_const_arg(arg.span(), err) {
|
||||
|
@ -2558,7 +2558,7 @@ impl<'a> Parser<'a> {
|
|||
let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
|
||||
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
|
||||
err.multipart_suggestion(
|
||||
&format!(
|
||||
format!(
|
||||
"try adding parentheses to match on a tuple{}",
|
||||
if let CommaRecoveryMode::LikelyTuple = rt { "" } else { "..." },
|
||||
),
|
||||
|
|
|
@ -855,7 +855,7 @@ impl<'a> Parser<'a> {
|
|||
_ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
|
||||
}
|
||||
);
|
||||
let mut err = self.struct_span_err(span, &msg);
|
||||
let mut err = self.struct_span_err(span, msg);
|
||||
|
||||
let suggest_parens = |err: &mut Diagnostic| {
|
||||
let suggestions = vec![
|
||||
|
@ -1803,7 +1803,7 @@ impl<'a> Parser<'a> {
|
|||
let token = self.token.clone();
|
||||
let err = |self_: &Self| {
|
||||
let msg = format!("unexpected token: {}", super::token_descr(&token));
|
||||
self_.struct_span_err(token.span, &msg)
|
||||
self_.struct_span_err(token.span, msg)
|
||||
};
|
||||
// On an error path, eagerly consider a lifetime to be an unclosed character lit
|
||||
if self.token.is_lifetime() {
|
||||
|
|
|
@ -71,7 +71,7 @@ impl<'a> Parser<'a> {
|
|||
if !self.eat(term) {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
if !self.maybe_consume_incorrect_semicolon(&items) {
|
||||
let msg = &format!("expected item, found {token_str}");
|
||||
let msg = format!("expected item, found {token_str}");
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
let label = if self.is_kw_followed_by_ident(kw::Let) {
|
||||
"consider using `const` or `static` instead of `let` for global variables"
|
||||
|
@ -1429,7 +1429,7 @@ impl<'a> Parser<'a> {
|
|||
VariantData::Struct(fields, recovered)
|
||||
} else {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let msg = &format!("expected `where` or `{{` after union name, found {token_str}");
|
||||
let msg = format!("expected `where` or `{{` after union name, found {token_str}");
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, "expected `where` or `{` after union name");
|
||||
return Err(err);
|
||||
|
@ -1465,7 +1465,7 @@ impl<'a> Parser<'a> {
|
|||
self.eat(&token::CloseDelim(Delimiter::Brace));
|
||||
} else {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let msg = &format!(
|
||||
let msg = format!(
|
||||
"expected {}`{{` after struct name, found {}",
|
||||
if parsed_where { "" } else { "`where`, or " },
|
||||
token_str
|
||||
|
@ -1602,7 +1602,7 @@ impl<'a> Parser<'a> {
|
|||
let sp = self.prev_token.span.shrink_to_hi();
|
||||
let mut err = self.struct_span_err(
|
||||
sp,
|
||||
&format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
|
||||
format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
|
||||
);
|
||||
|
||||
// Try to recover extra trailing angle brackets
|
||||
|
@ -1740,7 +1740,7 @@ impl<'a> Parser<'a> {
|
|||
Ok(_) => {
|
||||
let mut err = self.struct_span_err(
|
||||
lo.to(self.prev_token.span),
|
||||
&format!("functions are not allowed in {adt_ty} definitions"),
|
||||
format!("functions are not allowed in {adt_ty} definitions"),
|
||||
);
|
||||
err.help(
|
||||
"unlike in C++, Java, and C#, functions are declared in `impl` blocks",
|
||||
|
@ -1759,7 +1759,7 @@ impl<'a> Parser<'a> {
|
|||
Ok((ident, _)) => {
|
||||
let mut err = self.struct_span_err(
|
||||
lo.with_hi(ident.span.hi()),
|
||||
&format!("structs are not allowed in {adt_ty} definitions"),
|
||||
format!("structs are not allowed in {adt_ty} definitions"),
|
||||
);
|
||||
err.help("consider creating a new `struct` definition instead of nesting");
|
||||
err
|
||||
|
@ -2228,11 +2228,11 @@ impl<'a> Parser<'a> {
|
|||
|
||||
err.span_suggestion(
|
||||
self.token.uninterpolated_span(),
|
||||
&format!("`{original_kw}` already used earlier, remove this one"),
|
||||
format!("`{original_kw}` already used earlier, remove this one"),
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.span_note(original_sp, &format!("`{original_kw}` first seen here"));
|
||||
.span_note(original_sp, format!("`{original_kw}` first seen here"));
|
||||
}
|
||||
// The keyword has not been seen yet, suggest correct placement in the function front matter
|
||||
else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
|
||||
|
@ -2243,7 +2243,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
err.span_suggestion(
|
||||
correct_pos_sp.to(misplaced_qual_sp),
|
||||
&format!("`{misplaced_qual}` must come before `{current_qual}`"),
|
||||
format!("`{misplaced_qual}` must come before `{current_qual}`"),
|
||||
format!("{misplaced_qual} {current_qual}"),
|
||||
Applicability::MachineApplicable,
|
||||
).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
|
||||
|
@ -2267,7 +2267,7 @@ impl<'a> Parser<'a> {
|
|||
if matches!(orig_vis.kind, VisibilityKind::Inherited) {
|
||||
err.span_suggestion(
|
||||
sp_start.to(self.prev_token.span),
|
||||
&format!("visibility `{vs}` must come before `{snippet}`"),
|
||||
format!("visibility `{vs}` must come before `{snippet}`"),
|
||||
format!("{vs} {snippet}"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
|
|
@ -905,7 +905,7 @@ impl<'a> Parser<'a> {
|
|||
expect_err
|
||||
.span_suggestion_verbose(
|
||||
self.prev_token.span.shrink_to_hi().until(self.token.span),
|
||||
&msg,
|
||||
msg,
|
||||
" @ ",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
|
@ -921,7 +921,7 @@ impl<'a> Parser<'a> {
|
|||
expect_err
|
||||
.span_suggestion_short(
|
||||
sp,
|
||||
&format!("missing `{}`", token_str),
|
||||
format!("missing `{}`", token_str),
|
||||
token_str,
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
|
|
|
@ -444,7 +444,7 @@ impl<'a> Parser<'a> {
|
|||
super::token_descr(&self_.token)
|
||||
);
|
||||
|
||||
let mut err = self_.struct_span_err(self_.token.span, &msg);
|
||||
let mut err = self_.struct_span_err(self_.token.span, msg);
|
||||
err.span_label(self_.token.span, format!("expected {}", expected));
|
||||
err
|
||||
});
|
||||
|
@ -680,7 +680,7 @@ impl<'a> Parser<'a> {
|
|||
let expected = Expected::to_string_or_fallback(expected);
|
||||
let msg = format!("expected {}, found {}", expected, super::token_descr(&self.token));
|
||||
|
||||
let mut err = self.struct_span_err(self.token.span, &msg);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, format!("expected {}", expected));
|
||||
|
||||
let sp = self.sess.source_map().start_point(self.token.span);
|
||||
|
@ -978,7 +978,7 @@ impl<'a> Parser<'a> {
|
|||
break;
|
||||
}
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let msg = &format!("expected `}}`, found {}", token_str);
|
||||
let msg = format!("expected `}}`, found {}", token_str);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
|
||||
err.span_label(self.token.span, "expected `}`");
|
||||
|
|
|
@ -679,14 +679,14 @@ impl<'a> Parser<'a> {
|
|||
);
|
||||
err.span_suggestion(
|
||||
eq.to(before_next),
|
||||
&format!("remove the `=` if `{}` is a type", ident),
|
||||
format!("remove the `=` if `{}` is a type", ident),
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
} else {
|
||||
err.span_label(
|
||||
self.token.span,
|
||||
&format!("expected type, found {}", super::token_descr(&self.token)),
|
||||
format!("expected type, found {}", super::token_descr(&self.token)),
|
||||
)
|
||||
};
|
||||
return Err(err);
|
||||
|
|
|
@ -634,7 +634,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
e.span_suggestion(
|
||||
sp.with_hi(sp.lo() + BytePos(marker.len() as u32)),
|
||||
&format!(
|
||||
format!(
|
||||
"add a space before `{}` to use a regular comment",
|
||||
doc_comment_marker,
|
||||
),
|
||||
|
|
|
@ -315,7 +315,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
} else {
|
||||
let msg = format!("expected type, found {}", super::token_descr(&self.token));
|
||||
let mut err = self.struct_span_err(self.token.span, &msg);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, "expected type");
|
||||
return Err(err);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue