Add suggestion to quote inlined format argument as string literal

This commit is contained in:
Sebastian Toh 2023-08-05 17:23:33 +08:00
parent fca59ab5f0
commit d003fd9859
3 changed files with 113 additions and 12 deletions

View File

@ -1,6 +1,6 @@
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{token, StmtKind};
use rustc_ast::{
Expr, ExprKind, FormatAlignment, FormatArgPosition, FormatArgPositionKind, FormatArgs,
FormatArgsPiece, FormatArgument, FormatArgumentKind, FormatArguments, FormatCount,
@ -163,7 +163,7 @@ fn make_format_args(
let MacroInput { fmtstr: efmt, mut args, is_direct_literal } = input;
let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt, msg) {
let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt.clone(), msg) {
Ok(mut fmt) if append_newline => {
fmt.0 = Symbol::intern(&format!("{}\n", fmt.0));
fmt
@ -171,17 +171,33 @@ fn make_format_args(
Ok(fmt) => fmt,
Err(err) => {
if let Some((mut err, suggested)) = err {
let sugg_fmt = match args.explicit_args().len() {
0 => "{}".to_string(),
_ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
};
if !suggested {
err.span_suggestion(
unexpanded_fmt_span.shrink_to_lo(),
"you might be missing a string literal to format with",
format!("\"{sugg_fmt}\", "),
Applicability::MaybeIncorrect,
);
if let ExprKind::Block(block, None) = &efmt.kind
&& block.stmts.len() == 1
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
&& let ExprKind::Path(None, path) = &expr.kind
&& path.is_potential_trivial_const_arg()
{
err.multipart_suggestion(
"quote your inlined format argument to use as string literal",
vec![
(unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()),
(unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()),
],
Applicability::MaybeIncorrect,
);
} else {
let sugg_fmt = match args.explicit_args().len() {
0 => "{}".to_string(),
_ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
};
err.span_suggestion(
unexpanded_fmt_span.shrink_to_lo(),
"you might be missing a string literal to format with",
format!("\"{sugg_fmt}\", "),
Applicability::MaybeIncorrect,
);
}
}
err.emit();
}

View File

@ -0,0 +1,28 @@
mod foo {
pub fn bar() -> i32 {
1
}
}
fn bar() -> i32 {
2
}
fn main() {
let stderr = 3;
eprintln!({stderr});
//~^ ERROR format argument must be a string literal
//~| HELP quote your inlined format argument to use as string literal
eprintln!({1});
//~^ ERROR format argument must be a string literal
//~| HELP you might be missing a string literal to format with
eprintln!({foo::bar()});
//~^ ERROR format argument must be a string literal
//~| HELP you might be missing a string literal to format with
eprintln!({bar()});
//~^ ERROR format argument must be a string literal
//~| HELP you might be missing a string literal to format with
eprintln!({1; 2});
//~^ ERROR format argument must be a string literal
//~| HELP you might be missing a string literal to format with
}

View File

@ -0,0 +1,57 @@
error: format argument must be a string literal
--> $DIR/suggest-inline-args.rs:13:15
|
LL | eprintln!({stderr});
| ^^^^^^^^
|
help: quote your inlined format argument to use as string literal
|
LL | eprintln!("{stderr}");
| + +
error: format argument must be a string literal
--> $DIR/suggest-inline-args.rs:16:15
|
LL | eprintln!({1});
| ^^^
|
help: you might be missing a string literal to format with
|
LL | eprintln!("{}", {1});
| +++++
error: format argument must be a string literal
--> $DIR/suggest-inline-args.rs:19:15
|
LL | eprintln!({foo::bar()});
| ^^^^^^^^^^^^
|
help: you might be missing a string literal to format with
|
LL | eprintln!("{}", {foo::bar()});
| +++++
error: format argument must be a string literal
--> $DIR/suggest-inline-args.rs:22:15
|
LL | eprintln!({bar()});
| ^^^^^^^
|
help: you might be missing a string literal to format with
|
LL | eprintln!("{}", {bar()});
| +++++
error: format argument must be a string literal
--> $DIR/suggest-inline-args.rs:25:15
|
LL | eprintln!({1; 2});
| ^^^^^^
|
help: you might be missing a string literal to format with
|
LL | eprintln!("{}", {1; 2});
| +++++
error: aborting due to 5 previous errors