1
Fork 0

Auto merge of #102519 - Alexendoo:format-args-macro-str, r=m-ou-se

Fix `format_args` capture for macro expanded format strings

Since #100996 `format_args` capture for macro expanded strings aren't prevented when the span of the expansion points to a string literal, e.g.

```rust
// not a terribly realistic example, but also happens for proc_macros that set
// the span of the output to an input str literal, such as indoc
macro_rules! x {
    ($e:expr) => { $e }
}

fn main() {
    let a = 1;
    println!(x!("{a}"));
}
```

The tests didn't catch it as the span of `concat!()` points to the macro invocation

r? `@m-ou-se`
This commit is contained in:
bors 2022-10-01 14:15:29 +00:00
commit edadc7ccdd
7 changed files with 111 additions and 17 deletions

View file

@ -159,7 +159,7 @@ pub fn make_format_args(
append_newline: bool,
) -> Result<FormatArgs, ()> {
let msg = "format argument must be a string literal";
let fmt_span = efmt.span;
let unexpanded_fmt_span = efmt.span;
let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt, msg) {
Ok(mut fmt) if append_newline => {
fmt.0 = Symbol::intern(&format!("{}\n", fmt.0));
@ -174,7 +174,7 @@ pub fn make_format_args(
};
if !suggested {
err.span_suggestion(
fmt_span.shrink_to_lo(),
unexpanded_fmt_span.shrink_to_lo(),
"you might be missing a string literal to format with",
format!("\"{}\", ", sugg_fmt),
Applicability::MaybeIncorrect,
@ -192,7 +192,7 @@ pub fn make_format_args(
};
let fmt_str = fmt_str.as_str(); // for the suggestions below
let fmt_snippet = ecx.source_map().span_to_snippet(fmt_span).ok();
let fmt_snippet = ecx.source_map().span_to_snippet(unexpanded_fmt_span).ok();
let mut parser = parse::Parser::new(
fmt_str,
str_style,