diff --git a/packages/rsx/src/ifmt.rs b/packages/rsx/src/ifmt.rs index d7cbdadd6..fc4eac383 100644 --- a/packages/rsx/src/ifmt.rs +++ b/packages/rsx/src/ifmt.rs @@ -1,8 +1,8 @@ -use std::{collections::HashSet, str::FromStr}; +use std::str::FromStr; use proc_macro2::{Span, TokenStream}; -use quote::{quote, ToTokens, TokenStreamExt}; +use quote::{quote, quote_spanned, ToTokens, TokenStreamExt}; use syn::{ parse::{Parse, ParseStream}, *, @@ -188,20 +188,10 @@ impl ToTokens for IfmtInput { for segment in self.segments.iter() { match segment { Segment::Literal(s) => format_literal += &s.replace('{', "{{").replace('}', "}}"), - Segment::Formatted(FormattedSegment { - format_args, - segment, - }) => { + Segment::Formatted(FormattedSegment { format_args, .. }) => { format_literal += "{"; - match segment { - FormattedSegmentType::Expr(_) => { - format_literal += &expr_counter.to_string(); - expr_counter += 1; - } - FormattedSegmentType::Ident(ident) => { - format_literal += &ident.to_string(); - } - } + format_literal += &expr_counter.to_string(); + expr_counter += 1; format_literal += ":"; format_literal += format_args; format_literal += "}"; @@ -209,43 +199,29 @@ impl ToTokens for IfmtInput { } } + let span = match self.source.as_ref() { + Some(source) => source.span(), + None => Span::call_site(), + }; + let positional_args = self.segments.iter().filter_map(|seg| { - if let Segment::Formatted(FormattedSegment { - segment: FormattedSegmentType::Expr(expr), - .. - }) = seg - { - Some(expr) + if let Segment::Formatted(FormattedSegment { segment, .. }) = seg { + let mut segment = segment.clone(); + // We set the span of the ident here, so that we can use it in diagnostics + if let FormattedSegmentType::Ident(ident) = &mut segment { + ident.set_span(span); + } + Some(segment) } else { None } }); - // remove duplicate idents - let named_args_idents: HashSet<_> = self - .segments - .iter() - .filter_map(|seg| { - if let Segment::Formatted(FormattedSegment { - segment: FormattedSegmentType::Ident(ident), - .. - }) = seg - { - Some(ident) - } else { - None - } - }) - .collect(); - let named_args = named_args_idents - .iter() - .map(|ident| quote!(#ident = #ident)); - - quote! { + quote_spanned! { + span => ::std::format_args!( #format_literal #(, #positional_args)* - #(, #named_args)* ) } .to_tokens(tokens) diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index b3b363e09..58d96810d 100644 --- a/packages/rsx/src/lib.rs +++ b/packages/rsx/src/lib.rs @@ -110,20 +110,6 @@ impl Parse for CallBody { } } -/// Serialize the same way, regardless of flavor -impl ToTokens for CallBody { - fn to_tokens(&self, out_tokens: &mut TokenStream2) { - let body = TemplateRenderer { - roots: &self.roots, - location: None, - }; - - out_tokens.append_all(quote! { - #body - }) - } -} - #[derive(Default, Debug)] pub struct RenderCallBody(pub CallBody);