about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhkalbasi <hamidrezakalbasi@protonmail.com>2023-06-08 00:17:22 +0330
committerhkalbasi <hamidrezakalbasi@protonmail.com>2023-06-08 00:17:22 +0330
commit30e16e20d0f99efc025f2e6286b46f8217a7b682 (patch)
tree0d678fc18a9cea2b462ca67a4d8cca1b5db4d859
parentdcab22621024bb48e65c22b8dfbbae0f41da6931 (diff)
downloadrust-30e16e20d0f99efc025f2e6286b46f8217a7b682.tar.gz
rust-30e16e20d0f99efc025f2e6286b46f8217a7b682.zip
Fix unwrap on None in expanding format args
-rw-r--r--crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs38
-rw-r--r--crates/hir-expand/src/builtin_fn_macro.rs7
2 files changed, 41 insertions, 4 deletions
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index 977f300636f..541b0ad7066 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -208,6 +208,44 @@ fn main() {
 }
 
 #[test]
+fn regression_15002() {
+    check(
+        r#"
+#[rustc_builtin_macro]
+macro_rules! format_args {
+    ($fmt:expr) => ({ /* compiler built-in */ });
+    ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+}
+
+fn main() {
+    format_args!(x = 2);
+    format_args!(x =);
+    format_args!(x =, x = 2);
+    format_args!("{}", x =);
+    format_args!(=, "{}", x =);
+    format_args!(x = 2, "{}", 5);
+}
+"#,
+        expect![[r##"
+#[rustc_builtin_macro]
+macro_rules! format_args {
+    ($fmt:expr) => ({ /* compiler built-in */ });
+    ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+}
+
+fn main() {
+    /* error: no rule matches input tokens */;
+    /* error: no rule matches input tokens */;
+    /* error: no rule matches input tokens */;
+    /* error: no rule matches input tokens */::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::Argument::new(&(), ::core::fmt::Display::fmt), ]);
+    /* error: no rule matches input tokens */;
+    ::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::Argument::new(&(5), ::core::fmt::Display::fmt), ]);
+}
+"##]],
+    );
+}
+
+#[test]
 fn test_format_args_expand_with_comma_exprs() {
     check(
         r#"
diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs
index c7643bd0a18..5f47fd90c5c 100644
--- a/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/crates/hir-expand/src/builtin_fn_macro.rs
@@ -262,9 +262,6 @@ fn format_args_expand_general(
     let expand_error =
         ExpandResult::new(tt::Subtree::empty(), mbe::ExpandError::NoMatchingRule.into());
 
-    if args.is_empty() {
-        return expand_error;
-    }
     let mut key_args = FxHashMap::default();
     let mut args = args.into_iter().filter_map(|mut arg| {
         // Remove `key =`.
@@ -281,7 +278,9 @@ fn format_args_expand_general(
         Some(arg)
     }).collect::<Vec<_>>().into_iter();
     // ^^^^^^^ we need this collect, to enforce the side effect of the filter_map closure (building the `key_args`)
-    let format_subtree = args.next().unwrap();
+    let Some(format_subtree) = args.next() else {
+        return expand_error;
+    };
     let format_string = (|| {
         let token_tree = format_subtree.token_trees.get(0)?;
         match token_tree {