diff --git a/askama_derive/src/generator/node.rs b/askama_derive/src/generator/node.rs index 06a92918..7c4eea98 100644 --- a/askama_derive/src/generator/node.rs +++ b/askama_derive/src/generator/node.rs @@ -965,7 +965,11 @@ impl<'a> Generator<'a, '_> { } self.visit_target(buf, true, true, &l.var); - let (before, after) = if !is_copyable(val) { + // If it's not taking the ownership of a local variable or copyable, then we need to add + // a reference. + let (before, after) = if !matches!(**val, Expr::Var(name) if self.locals.get(name).is_some()) + && !is_copyable(val) + { ("&(", ")") } else { ("", "") diff --git a/testing/tests/vars.rs b/testing/tests/vars.rs index aac32042..5e3b4325 100644 --- a/testing/tests/vars.rs +++ b/testing/tests/vars.rs @@ -151,3 +151,48 @@ fn test_not_moving_fields_in_var() { }; assert_eq!(x.render().unwrap(), "a/a"); } + +// Ensure that using a local variable as value when creating +// another variable will not be behind a reference. +#[test] +fn test_moving_local_vars() { + #[derive(Template)] + #[template( + source = r#" +{%- let a = 1 -%} +{%- if a == 1 %}A{% endif -%} +{%- let b = a -%} +{%- if b == 1 %}B{% endif -%} +{%- let c = a + 0 -%} +{%- if c == 1 %}C{% endif -%} +{% let d = x %} +{%- if *d == 1 %}D{% endif -%} +{%- let e = y -%} +{%- if e == "a" %}E{% endif -%} +{%- let f = Bla::new() -%} +{%- if f.x == 0 %}F{% endif -%} +{%- let g = f.x -%} +{%- if *g == 0 %}G{% endif -%} + "#, + ext = "txt" + )] + struct X { + x: u32, + y: String, + } + struct Bla { + x: u32, + } + + impl Bla { + fn new() -> Self { + Self { x: 0 } + } + } + + let x = X { + x: 1, + y: "a".to_owned(), + }; + assert_eq!(x.render().unwrap(), "ABCDEFG"); +}