about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros
diff options
context:
space:
mode:
authorSebastian Toh <sebas.tsj.98@gmail.com>2023-08-05 17:23:33 +0800
committerSebastian Toh <sebas.tsj.98@gmail.com>2023-08-05 17:29:06 +0800
commitd003fd985976ce65d446243df182c935e5395334 (patch)
tree3af00c4f814aac87fdb20df7fc57d4029fd23cda /compiler/rustc_builtin_macros
parentfca59ab5f0e7df7d816bed77a32abc0045ebe80b (diff)
downloadrust-d003fd985976ce65d446243df182c935e5395334.tar.gz
rust-d003fd985976ce65d446243df182c935e5395334.zip
Add suggestion to quote inlined format argument as string literal
Diffstat (limited to 'compiler/rustc_builtin_macros')
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs40
1 files changed, 28 insertions, 12 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 590db12a4cd..ede95dbf897 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -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();
             }