This repository was archived by the owner on Mar 11, 2025. It is now read-only.
-
-
Couldn't load subscription status.
- Fork 221
This repository was archived by the owner on Mar 11, 2025. It is now read-only.
Iterating over elements of an iterator inside a macro moves the inner collection #708
Copy link
Copy link
Open
Description
For some reason, askama won't use references of the inner collection when using macros, resulting in a compiler error
error[E0507]: cannot move out of `foo.list` which is behind a shared reference
--> src/main.rs:
|
280 | #[derive(Template)]
| ^^^^^^^^
| |
| `foo.list` moved due to this method call
| move occurs because `foo.list` has type `BTreeSet<std::string::String>`, which does not implement the `Copy` trait
|
note: this function takes ownership of the receiver `self`, which moves `foo.list`
--> /usr/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:261:18
|
261 | fn into_iter(self) -> Self::IntoIter;
| ^^^^
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0507]: cannot move out of `foo.list` which is behind a shared reference
--> src/main.rs:
|
280 | #[derive(Template)]
| ^^^^^^^^
| |
| `foo.list` moved due to this method call
| move occurs because `foo.list` has type `BTreeSet<std::string::String>`, which does not implement the `Copy` trait
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
When taking the code from the macro body and placing it at the call side, it works as expected.
This is a minimal template to reproduce the problem:
{%- macro list(list) -%}
<ul>
{%- for item in list %}
<li>{{item}}</li>
{%- endfor %}
</ul>
<ol>
{%- for item in list %}
<li>{{item}}</li>
{%- endfor %}
</ol>
{%- endmacro -%}
{%- for foo in foos %}
{% call list(foo.list) %}
{%- endfor %}#[derive(Template)]
#[template(path = "list.j2", print = "code")]
struct List {
foos: Vec<Foo>
}
struct Foo {
list: BTreeSet<String>
}Generated code by askama
impl ::askama::Template for List {
fn render_into(&self, writer: &mut (impl ::std::fmt::Write + ?Sized)) -> ::askama::Result<()> {
include_bytes! ("/path/to/list.j2") ;
{
let mut _did_loop = false;
let _iter = (&self.foos).into_iter();
for (foo, _loop_item) in ::askama::helpers::TemplateLoop::new(_iter) {
_did_loop = true;
writer.write_str("\n")?;
{
writer.write_str("<ul>")?;
{
let mut _did_loop = false;
let _iter = (foo.list).into_iter();
for (item, _loop_item) in ::askama::helpers::TemplateLoop::new(_iter) {
_did_loop = true;
::std::write!(
writer,
"\n\t<li>{expr0}</li>",
expr0 = &::askama::MarkupDisplay::new_unsafe(&(item), ::askama::Html),
)?;
}
if !_did_loop {
}
}
writer.write_str("\n</ul>\n<ol>")?;
{
let mut _did_loop = false;
let _iter = (foo.list).into_iter();
for (item, _loop_item) in ::askama::helpers::TemplateLoop::new(_iter) {
_did_loop = true;
::std::write!(
writer,
"\n\t<li>{expr1}</li>",
expr1 = &::askama::MarkupDisplay::new_unsafe(&(item), ::askama::Html),
)?;
}
if !_did_loop {
}
}
writer.write_str("\n</ol>")?;
}
}
if !_did_loop {
}
}
::askama::Result::Ok(())
}
const EXTENSION: ::std::option::Option<&'static ::std::primitive::str> =
Some("j2")
;
const SIZE_HINT: ::std::primitive::usize =
0
;
const MIME_TYPE: &'static ::std::primitive::str =
"application/octet-stream"
;
}
impl ::std::fmt::Display for List {
#[inline]
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::askama::Template::render_into(self, f).map_err(|_| ::std::fmt::Error {})
}
}I'm using askama version 0.11.1 from crates.io.
Metadata
Metadata
Assignees
Labels
No labels