Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proc-macro derive panicked on range-based for loop. #117

Closed
sbwtw opened this issue Sep 20, 2018 · 5 comments
Closed

proc-macro derive panicked on range-based for loop. #117

sbwtw opened this issue Sep 20, 2018 · 5 comments

Comments

@sbwtw
Copy link

sbwtw commented Sep 20, 2018

{% for i in *start..*end %}
    {{ i }},
{% endfor %}
#[derive(Template)]
#[template(path = "for-range.html")]
struct ForRangeTemplate {
    start: usize,
    end: usize,
}

#[test]
fn test_for_range() {
    let s = ForTemplate {
        start:0, end: 3
    };
    assert_eq!(s.render().unwrap(), "0,1,2,");
}

output:

C:\Windows\system32\cmd.exe /c (cargo test -- test_for_range)
   Compiling askama_testing v0.1.0 (E:\Projects\askama\testing)
error: proc-macro derive panicked
  --> testing\tests\loops.rs:20:10
   |
20 | #[derive(Template)]
   |          ^^^^^^^^
   |
   = help: message: unable to parse template:

           "{% for i in *start..*end %}\r\n    {{ i }},\r\n{% endfor %}\r"

error: aborting due to previous error

error: Could not compile `askama_testing`.

To learn more, run the command again with --verbose.
shell returned 101
Hit any key to close this window...
@djc
Copy link
Owner

djc commented Sep 20, 2018

Yeah, Askama does not support & or * prefixes. It tries to do the right thing automatically there, but it probably doesn't always get it right. Did you try with just start and end, and if so, what error message do you get in that case?

@sbwtw
Copy link
Author

sbwtw commented Sep 20, 2018

@djc
for i in start..end

error[E0308]: mismatched types
  --> src\main.rs:62:10
   |
62 | #[derive(Template)]
   |          ^^^^^^^^
   |          |
   |          expected &usize, found usize
   |          help: consider borrowing here: `&Template`
   |
   = note: expected type `&usize`
              found type `usize`

error[E0599]: no method named `into_iter` found for type `std::ops::Range<&usize
>` in the current scope
  --> src\main.rs:62:10
   |
62 | #[derive(Template)]
   |          ^^^^^^^^
   |
   = note: the method `into_iter` exists but the following trait bounds were not
 satisfied:
           `std::ops::Range<&usize> : std::iter::IntoIterator`
           `&std::ops::Range<&usize> : std::iter::IntoIterator`
           `&mut std::ops::Range<&usize> : std::iter::IntoIterator`

error: aborting due to 2 previous errors

Some errors occurred: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.

and even literal integer for i in 0..3 is not work too:

error[E0308]: mismatched types
  --> src\main.rs:62:10
   |
62 | #[derive(Template)]
   |          ^^^^^^^^
   |          |
   |          expected &{integer}, found integral variable
   |          help: consider borrowing here: `&Template`
   |
   = note: expected type `&{integer}`
              found type `{integer}`

error[E0599]: no method named `into_iter` found for type `std::ops::Range<&{inte
ger}>` in the current scope
  --> src\main.rs:62:10
   |
62 | #[derive(Template)]
   |          ^^^^^^^^
   |
   = note: the method `into_iter` exists but the following trait bounds were not
 satisfied:
           `std::ops::Range<&{integer}> : std::iter::IntoIterator`
           `&std::ops::Range<&{integer}> : std::iter::IntoIterator`
           `&mut std::ops::Range<&{integer}> : std::iter::IntoIterator`

error: aborting due to 2 previous errors

Some errors occurred: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.

@zzau13
Copy link
Contributor

zzau13 commented Sep 20, 2018

@djc You have to treat the ranges separately, like

 match iter {
            Expr::Range(_, _, _) => buf.writeln(&format!(") in ({}).enumerate() {{", expr_code)),
            _ => buf.writeln(&format!(") in (&{}).into_iter().enumerate() {{", expr_code)),
        };

I add coverage to this part and do the pull request

@zzau13
Copy link
Contributor

zzau13 commented Sep 21, 2018

The problem is that we can not differentiate between iterator and vector. We should always use iterators. And force the user to use them. It would be necessary to change several tests by adding .into_iter() to the html. Same of #107. I add to that pull request?

@djc djc closed this as completed Sep 21, 2018
@djc
Copy link
Owner

djc commented Sep 21, 2018

This has been fixed by @botika in #118. @sbwtw thanks for reporting, and @botika thanks for fixing!

@botika I don't want to require users to force users to pass actual Iterators into templates. Ideally we'd make it work in general for things that are IntoIterator as well as for things that are Iterator. Maybe we could do this by coming up with a more general internal trait?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants