add diagnostic for raw identifiers in format string
This commit is contained in:
parent
a0c28cd9dc
commit
d990eee0c8
6 changed files with 158 additions and 35 deletions
|
@ -137,6 +137,8 @@ builtin_macros_format_positional_after_named = positional arguments cannot follo
|
|||
.label = positional arguments must be before named arguments
|
||||
.named_args = named argument
|
||||
|
||||
builtin_macros_format_remove_raw_ident = remove the `r#`
|
||||
|
||||
builtin_macros_format_requires_string = requires at least a format string argument
|
||||
|
||||
builtin_macros_format_string_invalid = invalid format string: {$desc}
|
||||
|
@ -165,6 +167,8 @@ builtin_macros_format_unused_arg = {$named ->
|
|||
builtin_macros_format_unused_args = multiple unused formatting arguments
|
||||
.label = multiple missing formatting specifiers
|
||||
|
||||
builtin_macros_format_use_positional = consider using a positional formatting argument instead
|
||||
|
||||
builtin_macros_global_asm_clobber_abi = `clobber_abi` cannot be used with `global_asm!`
|
||||
|
||||
builtin_macros_invalid_crate_attribute = invalid crate attribute
|
||||
|
@ -205,8 +209,6 @@ builtin_macros_requires_cfg_pattern =
|
|||
|
||||
builtin_macros_should_panic = functions using `#[should_panic]` must return `()`
|
||||
|
||||
builtin_macros_sugg = consider using a positional formatting argument instead
|
||||
|
||||
builtin_macros_test_arg_non_lifetime = functions used as tests can not have any non-lifetime generic parameters
|
||||
|
||||
builtin_macros_test_args = functions used as tests can not have any arguments
|
||||
|
|
|
@ -539,18 +539,29 @@ pub(crate) struct InvalidFormatStringLabel {
|
|||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
builtin_macros_sugg,
|
||||
style = "verbose",
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct InvalidFormatStringSuggestion {
|
||||
#[suggestion_part(code = "{len}")]
|
||||
pub(crate) captured: Span,
|
||||
pub(crate) len: String,
|
||||
#[suggestion_part(code = ", {arg}")]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) arg: String,
|
||||
pub(crate) enum InvalidFormatStringSuggestion {
|
||||
#[multipart_suggestion(
|
||||
builtin_macros_format_use_positional,
|
||||
style = "verbose",
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
UsePositional {
|
||||
#[suggestion_part(code = "{len}")]
|
||||
captured: Span,
|
||||
len: String,
|
||||
#[suggestion_part(code = ", {arg}")]
|
||||
span: Span,
|
||||
arg: String,
|
||||
},
|
||||
#[suggestion(
|
||||
builtin_macros_format_remove_raw_ident,
|
||||
code = "",
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
RemoveRawIdent {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
@ -260,20 +260,29 @@ fn make_format_args(
|
|||
if let Some((label, span)) = err.secondary_label && is_source_literal {
|
||||
e.label_ = Some(errors::InvalidFormatStringLabel { span: fmt_span.from_inner(InnerSpan::new(span.start, span.end)), label } );
|
||||
}
|
||||
if err.should_be_replaced_with_positional_argument {
|
||||
let captured_arg_span =
|
||||
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
|
||||
if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) {
|
||||
let span = match args.unnamed_args().last() {
|
||||
Some(arg) => arg.expr.span,
|
||||
None => fmt_span,
|
||||
};
|
||||
e.sugg_ = Some(errors::InvalidFormatStringSuggestion {
|
||||
captured: captured_arg_span,
|
||||
len: args.unnamed_args().len().to_string(),
|
||||
span: span.shrink_to_hi(),
|
||||
arg,
|
||||
});
|
||||
match err.suggestion {
|
||||
parse::Suggestion::None => {}
|
||||
parse::Suggestion::UsePositional => {
|
||||
let captured_arg_span =
|
||||
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
|
||||
if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) {
|
||||
let span = match args.unnamed_args().last() {
|
||||
Some(arg) => arg.expr.span,
|
||||
None => fmt_span,
|
||||
};
|
||||
e.sugg_ = Some(errors::InvalidFormatStringSuggestion::UsePositional {
|
||||
captured: captured_arg_span,
|
||||
len: args.unnamed_args().len().to_string(),
|
||||
span: span.shrink_to_hi(),
|
||||
arg,
|
||||
});
|
||||
}
|
||||
}
|
||||
parse::Suggestion::RemoveRawIdent(span) => {
|
||||
if is_source_literal {
|
||||
let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end));
|
||||
e.sugg_ = Some(errors::InvalidFormatStringSuggestion::RemoveRawIdent { span })
|
||||
}
|
||||
}
|
||||
}
|
||||
ecx.emit_err(e);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue