mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-27 04:50:40 +00:00
Fix wrong macro argument parsing
This commit is contained in:
parent
e8d2391d48
commit
1f31021632
@ -927,6 +927,35 @@ impl<'a> Suffix<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lifetime<'a>(i: &mut InputStream<'a>) -> ParseResult<'a, ()> {
|
||||
// Before the 2021 edition, we can have whitespace characters between "r#" and the
|
||||
// identifier so we allow it here.
|
||||
let start = *i;
|
||||
'\''.parse_next(i)?;
|
||||
let Some((is_raw, identifier)) = opt(alt((
|
||||
('r', '#', identifier).map(|(_, _, ident)| (true, ident)),
|
||||
(identifier, not(peek('#'))).map(|(ident, _)| (false, ident)),
|
||||
)))
|
||||
.parse_next(i)?
|
||||
else {
|
||||
return cut_error!("wrong lifetime format", **start);
|
||||
};
|
||||
if !is_raw {
|
||||
if crate::is_rust_keyword(identifier) {
|
||||
return cut_error!(
|
||||
"a non-raw lifetime cannot be named like an existing keyword",
|
||||
**start,
|
||||
);
|
||||
}
|
||||
} else if ["Self", "self", "crate", "super", "_"].contains(&identifier) {
|
||||
return cut_error!(format!("`{identifier}` cannot be a raw lifetime"), **start,);
|
||||
}
|
||||
if opt(peek('\'')).parse_next(i)?.is_some() {
|
||||
return cut_error!("unexpected `'` after lifetime", **start);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn token<'a>(i: &mut InputStream<'a>) -> ParseResult<'a, Token> {
|
||||
// <https://doc.rust-lang.org/reference/tokens.html>
|
||||
let some_other = alt((
|
||||
@ -936,8 +965,7 @@ impl<'a> Suffix<'a> {
|
||||
num_lit.value(Token::SomeOther),
|
||||
// keywords + (raw) identifiers + raw strings
|
||||
identifier_or_prefixed_string.value(Token::SomeOther),
|
||||
// lifetimes
|
||||
('\'', identifier, not(peek('\''))).value(Token::SomeOther),
|
||||
lifetime.value(Token::SomeOther),
|
||||
// comments
|
||||
line_comment.value(Token::SomeOther),
|
||||
block_comment.value(Token::SomeOther),
|
||||
|
@ -0,0 +1 @@
|
||||
˙˙˙{{z!{'r#}}}˙ ˙s˙
|
@ -630,3 +630,19 @@ fn test_macro_caller_is_defined_check() {
|
||||
"no caller defined|this time with caller"
|
||||
);
|
||||
}
|
||||
|
||||
// This test ensures that raw lifetimes are correctly handled.
|
||||
#[test]
|
||||
fn test_macro_raw_lifetime() {
|
||||
macro_rules! test {
|
||||
('r#ignore_me) => {
|
||||
"ok"
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(source = r##"{{ test!('r#ignore_me) }}"##, ext = "txt")]
|
||||
struct Foo;
|
||||
|
||||
assert_eq!(Foo.render().unwrap(), "ok");
|
||||
}
|
||||
|
34
testing/tests/ui/macro-args-hashtag.rs
Normal file
34
testing/tests/ui/macro-args-hashtag.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// This test ensures that we have the right error if a `#` character isn't prepended by
|
||||
// a whitespace character and also that lifetimes are correctly handled.
|
||||
|
||||
use askama::Template;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(
|
||||
source = r###"{{z!{'r#}}}"###,
|
||||
ext = "html"
|
||||
)]
|
||||
struct Example;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(
|
||||
source = r###"{{z!{'r# y}}}"###,
|
||||
ext = "html"
|
||||
)]
|
||||
struct Example2;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(
|
||||
source = r###"{{z!{'break}}}"###,
|
||||
ext = "html"
|
||||
)]
|
||||
struct Example3;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(
|
||||
source = r###"{{z!{'r#self}}}"###,
|
||||
ext = "html"
|
||||
)]
|
||||
struct Example4;
|
||||
|
||||
fn main() {}
|
31
testing/tests/ui/macro-args-hashtag.stderr
Normal file
31
testing/tests/ui/macro-args-hashtag.stderr
Normal file
@ -0,0 +1,31 @@
|
||||
error: wrong lifetime format
|
||||
--> <source attribute>:1:5
|
||||
"'r#}}}"
|
||||
--> tests/ui/macro-args-hashtag.rs:8:14
|
||||
|
|
||||
8 | source = r###"{{z!{'r#}}}"###,
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: wrong lifetime format
|
||||
--> <source attribute>:1:5
|
||||
"'r# y}}}"
|
||||
--> tests/ui/macro-args-hashtag.rs:15:14
|
||||
|
|
||||
15 | source = r###"{{z!{'r# y}}}"###,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a non-raw lifetime cannot be named like an existing keyword
|
||||
--> <source attribute>:1:5
|
||||
"'break}}}"
|
||||
--> tests/ui/macro-args-hashtag.rs:22:14
|
||||
|
|
||||
22 | source = r###"{{z!{'break}}}"###,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `self` cannot be a raw lifetime
|
||||
--> <source attribute>:1:5
|
||||
"'r#self}}}"
|
||||
--> tests/ui/macro-args-hashtag.rs:29:14
|
||||
|
|
||||
29 | source = r###"{{z!{'r#self}}}"###,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
Loading…
x
Reference in New Issue
Block a user