From f62cdfb49aa1c160b8f6c6786a400d2713dfc8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Wed, 6 Aug 2025 17:02:39 +0200 Subject: [PATCH] derive: better spans for Target --- askama_derive/src/generator/expr.rs | 40 +++++++++-------------------- askama_derive/src/generator/node.rs | 14 +++++----- 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/askama_derive/src/generator/expr.rs b/askama_derive/src/generator/expr.rs index 27077d6b..e4fdf5fd 100644 --- a/askama_derive/src/generator/expr.rs +++ b/askama_derive/src/generator/expr.rs @@ -7,7 +7,7 @@ use parser::{ TyGenerics, WithSpan, }; use proc_macro2::TokenStream; -use quote::{quote, quote_spanned}; +use quote::quote_spanned; use syn::Token; use super::{ @@ -264,7 +264,7 @@ impl<'a> Generator<'a, '_> { let span = ctx.span_for_node(cond.span()); buf.write_token(Token![let], span); if let Some(ref target) = cond.target { - self.visit_target(ctx, buf, true, true, target); + self.visit_target(ctx, buf, true, true, target, span); } quote_into!(buf, span, { = &#expr_buf }); self.visit_expr_not_first(ctx, buf, &cond.expr, display_wrap) @@ -508,7 +508,7 @@ impl<'a> Generator<'a, '_> { } let tmp = tmp.into_token_stream(); // FIXME: use a better span - buf.write(quote!(<#tmp>), ctx.template_span); + quote_into!(buf, ctx.template_span, { <#tmp> }); } pub(super) fn visit_ty_generic( @@ -911,6 +911,7 @@ impl<'a> Generator<'a, '_> { initialized: bool, first_level: bool, target: &Target<'a>, + span: proc_macro2::Span, ) { match target { Target::Placeholder(s) => quote_into!(buf, ctx.span_for_node(s.span()), { _ }), @@ -936,10 +937,10 @@ impl<'a> Generator<'a, '_> { Target::OrChain(targets) => match targets.first() { None => quote_into!(buf, ctx.template_span, { _ }), Some(first_target) => { - self.visit_target(ctx, buf, initialized, first_level, first_target); + self.visit_target(ctx, buf, initialized, first_level, first_target, span); for target in &targets[1..] { buf.write_token(Token![|], ctx.template_span); - self.visit_target(ctx, buf, initialized, first_level, target); + self.visit_target(ctx, buf, initialized, first_level, target, span); } } }, @@ -947,31 +948,21 @@ impl<'a> Generator<'a, '_> { buf.write_separated_path(ctx, path); let mut targets_buf = Buffer::new(); for target in targets { - self.visit_target(ctx, &mut targets_buf, initialized, false, target); + self.visit_target(ctx, &mut targets_buf, initialized, false, target, span); targets_buf.write_token(Token![,], ctx.template_span); } let targets_buf = targets_buf.into_token_stream(); - buf.write( - quote!( - (#targets_buf) - ), - ctx.template_span, - ); + quote_into!(buf, span, { (#targets_buf) }); } Target::Array(path, targets) => { buf.write_separated_path(ctx, path); let mut targets_buf = Buffer::new(); for target in targets { - self.visit_target(ctx, &mut targets_buf, initialized, false, target); + self.visit_target(ctx, &mut targets_buf, initialized, false, target, span); targets_buf.write_token(Token![,], ctx.template_span); } let targets_buf = targets_buf.into_token_stream(); - buf.write( - quote!( - [#targets_buf] - ), - ctx.template_span, - ); + quote_into!(buf, span, { [#targets_buf] }); } Target::Struct(path, targets) => { buf.write_separated_path(ctx, path); @@ -984,18 +975,11 @@ impl<'a> Generator<'a, '_> { targets_buf.write_field(name, ctx.template_span); targets_buf.write_token(Token![:], ctx.template_span); - self.visit_target(ctx, &mut targets_buf, initialized, false, target); + self.visit_target(ctx, &mut targets_buf, initialized, false, target, span); targets_buf.write_token(Token![,], ctx.template_span); } let targets_buf = targets_buf.into_token_stream(); - buf.write( - quote!( - { - #targets_buf - } - ), - ctx.template_span, - ); + quote_into!(buf, span, { { #targets_buf } }); } Target::Path(path) => { self.visit_path(ctx, buf, path); diff --git a/askama_derive/src/generator/node.rs b/askama_derive/src/generator/node.rs index 6bfe5980..60eafd8f 100644 --- a/askama_derive/src/generator/node.rs +++ b/askama_derive/src/generator/node.rs @@ -369,7 +369,7 @@ impl<'a> Generator<'a, '_> { Expr::BinOp(v) if matches!(v.op, "||" | "&&") => { let display_wrap = this.visit_expr_first(ctx, &mut expr_buf, &v.lhs)?; - this.visit_target(ctx, buf, true, true, target); + this.visit_target(ctx, buf, true, true, target, span); this.visit_expr_not_first( ctx, &mut expr_buf, @@ -383,7 +383,7 @@ impl<'a> Generator<'a, '_> { _ => { let display_wrap = this.visit_expr_first(ctx, &mut expr_buf, expr)?; - this.visit_target(ctx, buf, true, true, target); + this.visit_target(ctx, buf, true, true, target, span); this.visit_expr_not_first(ctx, &mut expr_buf, expr, display_wrap)?; quote_into!(buf, ctx.template_span, { = &#expr_buf }); } @@ -474,7 +474,7 @@ impl<'a> Generator<'a, '_> { if index != 0 { targets_buf.write_token(Token![|], span); } - this.visit_target(ctx, &mut targets_buf, true, true, target); + this.visit_target(ctx, &mut targets_buf, true, true, target, span); } let mut arm_buf = Buffer::new(); @@ -527,7 +527,7 @@ impl<'a> Generator<'a, '_> { if let Some(cond) = &loop_block.cond { this.push_locals(|this| { let mut target_buf = Buffer::new(); - this.visit_target(ctx, &mut target_buf, true, true, &loop_block.var); + this.visit_target(ctx, &mut target_buf, true, true, &loop_block.var, span); let target_buf = target_buf.into_token_stream(); let mut expr_buf = Buffer::new(); this.visit_expr(ctx, &mut expr_buf, cond)?; @@ -549,7 +549,7 @@ impl<'a> Generator<'a, '_> { let size_hint1 = this.push_locals(|this| { let mut target_buf = Buffer::new(); - this.visit_target(ctx, &mut target_buf, true, true, &loop_block.var); + this.visit_target(ctx, &mut target_buf, true, true, &loop_block.var, span); let target_buf = target_buf.into_token_stream(); let mut loop_body_buf = Buffer::new(); @@ -837,7 +837,7 @@ impl<'a> Generator<'a, '_> { if l.is_mutable { buf.write_token(Token![mut], span); } - self.visit_target(ctx, buf, false, true, &l.var); + self.visit_target(ctx, buf, false, true, &l.var, span); buf.write_token(Token![;], span); return Ok(()); }; @@ -871,7 +871,7 @@ impl<'a> Generator<'a, '_> { } } - self.visit_target(ctx, buf, true, true, &l.var); + self.visit_target(ctx, buf, true, true, &l.var, span); // If it's not taking the ownership of a local variable or copyable, then we need to add // a reference. let borrow = !matches!(***val, Expr::Try(..))