Skip to content

Commit e286f25

Browse files
committed
Auto merge of rust-lang#114507 - sebastiantoh:issue-114235, r=jackh726
Add suggestion to quote inlined format argument as string literal Fixes rust-lang#114235
2 parents a9b2c6a + d003fd9 commit e286f25

File tree

3 files changed

+113
-12
lines changed

3 files changed

+113
-12
lines changed

compiler/rustc_builtin_macros/src/format.rs

+28-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::ptr::P;
2-
use rustc_ast::token;
32
use rustc_ast::tokenstream::TokenStream;
3+
use rustc_ast::{token, StmtKind};
44
use rustc_ast::{
55
Expr, ExprKind, FormatAlignment, FormatArgPosition, FormatArgPositionKind, FormatArgs,
66
FormatArgsPiece, FormatArgument, FormatArgumentKind, FormatArguments, FormatCount,
@@ -163,25 +163,41 @@ fn make_format_args(
163163

164164
let MacroInput { fmtstr: efmt, mut args, is_direct_literal } = input;
165165

166-
let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt, msg) {
166+
let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt.clone(), msg) {
167167
Ok(mut fmt) if append_newline => {
168168
fmt.0 = Symbol::intern(&format!("{}\n", fmt.0));
169169
fmt
170170
}
171171
Ok(fmt) => fmt,
172172
Err(err) => {
173173
if let Some((mut err, suggested)) = err {
174-
let sugg_fmt = match args.explicit_args().len() {
175-
0 => "{}".to_string(),
176-
_ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
177-
};
178174
if !suggested {
179-
err.span_suggestion(
180-
unexpanded_fmt_span.shrink_to_lo(),
181-
"you might be missing a string literal to format with",
182-
format!("\"{sugg_fmt}\", "),
183-
Applicability::MaybeIncorrect,
184-
);
175+
if let ExprKind::Block(block, None) = &efmt.kind
176+
&& block.stmts.len() == 1
177+
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
178+
&& let ExprKind::Path(None, path) = &expr.kind
179+
&& path.is_potential_trivial_const_arg()
180+
{
181+
err.multipart_suggestion(
182+
"quote your inlined format argument to use as string literal",
183+
vec![
184+
(unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()),
185+
(unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()),
186+
],
187+
Applicability::MaybeIncorrect,
188+
);
189+
} else {
190+
let sugg_fmt = match args.explicit_args().len() {
191+
0 => "{}".to_string(),
192+
_ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
193+
};
194+
err.span_suggestion(
195+
unexpanded_fmt_span.shrink_to_lo(),
196+
"you might be missing a string literal to format with",
197+
format!("\"{sugg_fmt}\", "),
198+
Applicability::MaybeIncorrect,
199+
);
200+
}
185201
}
186202
err.emit();
187203
}

tests/ui/fmt/suggest-inline-args.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
mod foo {
2+
pub fn bar() -> i32 {
3+
1
4+
}
5+
}
6+
7+
fn bar() -> i32 {
8+
2
9+
}
10+
11+
fn main() {
12+
let stderr = 3;
13+
eprintln!({stderr});
14+
//~^ ERROR format argument must be a string literal
15+
//~| HELP quote your inlined format argument to use as string literal
16+
eprintln!({1});
17+
//~^ ERROR format argument must be a string literal
18+
//~| HELP you might be missing a string literal to format with
19+
eprintln!({foo::bar()});
20+
//~^ ERROR format argument must be a string literal
21+
//~| HELP you might be missing a string literal to format with
22+
eprintln!({bar()});
23+
//~^ ERROR format argument must be a string literal
24+
//~| HELP you might be missing a string literal to format with
25+
eprintln!({1; 2});
26+
//~^ ERROR format argument must be a string literal
27+
//~| HELP you might be missing a string literal to format with
28+
}
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
error: format argument must be a string literal
2+
--> $DIR/suggest-inline-args.rs:13:15
3+
|
4+
LL | eprintln!({stderr});
5+
| ^^^^^^^^
6+
|
7+
help: quote your inlined format argument to use as string literal
8+
|
9+
LL | eprintln!("{stderr}");
10+
| + +
11+
12+
error: format argument must be a string literal
13+
--> $DIR/suggest-inline-args.rs:16:15
14+
|
15+
LL | eprintln!({1});
16+
| ^^^
17+
|
18+
help: you might be missing a string literal to format with
19+
|
20+
LL | eprintln!("{}", {1});
21+
| +++++
22+
23+
error: format argument must be a string literal
24+
--> $DIR/suggest-inline-args.rs:19:15
25+
|
26+
LL | eprintln!({foo::bar()});
27+
| ^^^^^^^^^^^^
28+
|
29+
help: you might be missing a string literal to format with
30+
|
31+
LL | eprintln!("{}", {foo::bar()});
32+
| +++++
33+
34+
error: format argument must be a string literal
35+
--> $DIR/suggest-inline-args.rs:22:15
36+
|
37+
LL | eprintln!({bar()});
38+
| ^^^^^^^
39+
|
40+
help: you might be missing a string literal to format with
41+
|
42+
LL | eprintln!("{}", {bar()});
43+
| +++++
44+
45+
error: format argument must be a string literal
46+
--> $DIR/suggest-inline-args.rs:25:15
47+
|
48+
LL | eprintln!({1; 2});
49+
| ^^^^^^
50+
|
51+
help: you might be missing a string literal to format with
52+
|
53+
LL | eprintln!("{}", {1; 2});
54+
| +++++
55+
56+
error: aborting due to 5 previous errors
57+

0 commit comments

Comments
 (0)