Browse Source

allow duplicate idents in format_args_f (#515)

Demonthos 2 years ago
parent
commit
baf1807338
2 changed files with 26 additions and 12 deletions
  1. 6 0
      packages/core-macro/tests/ifmt.rs
  2. 20 12
      packages/rsx/src/ifmt.rs

+ 6 - 0
packages/core-macro/tests/ifmt.rs

@@ -23,4 +23,10 @@ fn formatting_compiles() {
         format_args_f!("{x.borrow():?}").to_string(),
         format!("{:?}", x.borrow())
     );
+
+    // allows duplicate format args
+    assert_eq!(
+        format_args_f!("{x:?} {x:?}").to_string(),
+        format!("{:?} {:?}", x, x)
+    );
 }

+ 20 - 12
packages/rsx/src/ifmt.rs

@@ -1,4 +1,4 @@
-use std::str::FromStr;
+use std::{collections::HashSet, str::FromStr};
 
 use proc_macro2::{Span, TokenStream};
 
@@ -48,17 +48,25 @@ pub fn format_args_f_impl(input: IfmtInput) -> Result<TokenStream> {
         }
     });
 
-    let named_args = input.segments.iter().filter_map(|seg| {
-        if let Segment::Formatted {
-            segment: FormattedSegment::Ident(ident),
-            ..
-        } = seg
-        {
-            Some(quote! {#ident = #ident})
-        } else {
-            None
-        }
-    });
+    // remove duplicate idents
+    let named_args_idents: HashSet<_> = input
+        .segments
+        .iter()
+        .filter_map(|seg| {
+            if let Segment::Formatted {
+                segment: FormattedSegment::Ident(ident),
+                ..
+            } = seg
+            {
+                Some(ident)
+            } else {
+                None
+            }
+        })
+        .collect();
+    let named_args = named_args_idents
+        .iter()
+        .map(|ident| quote!(#ident = #ident));
 
     Ok(quote! {
         format_args!(