parser: replace manual i_before with .with_taken()

This commit is contained in:
René Kijewski 2025-06-24 14:37:18 +02:00 committed by René Kijewski
parent 1a1b507722
commit 4f5272406f
8 changed files with 37 additions and 45 deletions

View File

@ -33,11 +33,11 @@ fn expr_prec_layer<'a>(
let start = *i;
let mut expr = inner(i, level)?;
let mut i_before = *i;
let mut level_guard = level.guard();
while let Some((op, rhs)) = opt((ws(op), |i: &mut _| inner(i, level))).parse_next(i)? {
while let Some(((op, rhs), i_before)) =
opt((ws(op), |i: &mut _| inner(i, level)).with_taken()).parse_next(i)?
{
level_guard.nest(i_before)?;
i_before = *i;
expr = WithSpan::new(Expr::BinOp(Box::new(BinOp { op, lhs: expr, rhs })), start);
}
@ -480,12 +480,12 @@ impl<'a> Expr<'a> {
let mut res = Self::prefix(i, level)?;
let mut level_guard = level.guard();
let mut i_before = *i;
while let Some(mut filter) = opt(|i: &mut _| filter(i, level)).parse_next(i)? {
while let Some((mut filter, i_before)) =
opt(ws((|i: &mut _| filter(i, level)).with_taken())).parse_next(i)?
{
level_guard.nest(i_before)?;
filter.arguments.insert(0, res);
res = WithSpan::new(Self::Filter(Box::new(filter)), i_before);
i_before = *i;
}
Ok(res)
}
@ -498,11 +498,11 @@ impl<'a> Expr<'a> {
// to stack overflows in drop glue when the AST is very deep.
let mut level_guard = level.guard();
let mut ops = vec![];
let mut i_before = *i;
while let Some(op) = opt(ws(alt(("!", "-", "*", "&")))).parse_next(i)? {
while let Some((op, i_before)) =
opt(ws(alt(("!", "-", "*", "&")).with_taken())).parse_next(i)?
{
level_guard.nest(i_before)?;
ops.push(op);
i_before = *i;
}
let mut expr = Suffix::parse(i, level)?;
@ -706,30 +706,22 @@ impl<'a> Suffix<'a> {
fn parse(i: &mut &'a str, level: Level<'_>) -> ParseResult<'a, WithSpan<'a, Expr<'a>>> {
let mut level_guard = level.guard();
let mut expr = Expr::single(i, level)?;
let mut right = opt(alt((
let mut right = alt((
|i: &mut _| Self::associated_item(i, level),
|i: &mut _| Self::index(i, level),
|i: &mut _| Self::call(i, level),
Self::r#try,
Self::r#macro,
)));
loop {
let before_suffix = *i;
let suffix = right.parse_next(i)?;
let Some(suffix) = suffix else {
break;
};
level_guard.nest(before_suffix)?;
));
while let Some((suffix, i_before)) = opt(right.by_ref().with_taken()).parse_next(i)? {
level_guard.nest(i_before)?;
match suffix {
Self::AssociatedItem(associated_item) => {
expr = WithSpan::new(
Expr::AssociatedItem(expr.into(), associated_item),
before_suffix,
)
expr =
WithSpan::new(Expr::AssociatedItem(expr.into(), associated_item), i_before)
}
Self::Index(index) => {
expr = WithSpan::new(Expr::Index(expr.into(), index.into()), before_suffix);
expr = WithSpan::new(Expr::Index(expr.into(), index.into()), i_before);
}
Self::Call { args, generics } => {
expr = WithSpan::new(
@ -738,21 +730,21 @@ impl<'a> Suffix<'a> {
args,
generics,
})),
before_suffix,
i_before,
)
}
Self::Try => expr = WithSpan::new(Expr::Try(expr.into()), before_suffix),
Self::Try => expr = WithSpan::new(Expr::Try(expr.into()), i_before),
Self::MacroCall(args) => match expr.inner {
Expr::Path(path) => {
ensure_macro_name(path.last().unwrap())?;
expr = WithSpan::new(Expr::RustMacro(path, args), before_suffix)
expr = WithSpan::new(Expr::RustMacro(path, args), i_before)
}
Expr::Var(name) => {
ensure_macro_name(name)?;
expr = WithSpan::new(Expr::RustMacro(vec![name], args), before_suffix)
expr = WithSpan::new(Expr::RustMacro(vec![name], args), i_before)
}
_ => {
return Err(ErrMode::from_input(&before_suffix).cut());
return Err(ErrMode::from_input(&i_before).cut());
}
},
}

View File

@ -1163,7 +1163,7 @@ impl LevelGuard<'_> {
fn filter<'a>(i: &mut &'a str, level: Level<'_>) -> ParseResult<'a, Filter<'a>> {
preceded(
ws(('|', not('|'))),
('|', not('|')),
cut_err(|i: &mut _| Filter::parse(i, level)),
)
.parse_next(i)

View File

@ -771,14 +771,14 @@ impl<'a> FilterBlock<'a> {
.insert(0, WithSpan::new(Expr::FilterSource, start));
let mut level_guard = s.level.guard();
let mut i_before = *i;
while let Some(mut filter) = opt(|i: &mut _| filter(i, s.level)).parse_next(i)? {
while let Some((mut filter, i_before)) =
opt(ws((|i: &mut _| filter(i, s.level)).with_taken())).parse_next(i)?
{
level_guard.nest(i_before)?;
filter
.arguments
.insert(0, WithSpan::new(Expr::Filter(Box::new(res)), i_before));
res = filter;
i_before = *i;
}
Ok(res)
}

View File

@ -1,6 +1,6 @@
error: `do_nothing` filter cannot accept named arguments
--> CustomFiltersCannotTakeNamedArguments.txt:1:3
"a | do_nothing(absolutely = \"nothing\") }}"
--> CustomFiltersCannotTakeNamedArguments.txt:1:5
"| do_nothing(absolutely = \"nothing\") }}"
--> tests/ui/custom-filter-with-named-arg.rs:12:21
|
12 | #[template(source = r#"{{ a | do_nothing(absolutely = "nothing") }}"#, ext = "txt")]

View File

@ -1,6 +1,6 @@
error: your template code is too deeply nested, or the last expression is too complex
--> testing/templates/filter-recursion.html:1:275
"|A|A|AA|A|A|A|A|AA|A|A|A|A|AA|A|A|A|A|AA|A|A|A||A|A|AA|A|A|A|A|AA|A|A|A|A|AA|A|A"...
--> testing/templates/filter-recursion.html:1:277
"|A|AA|A|A|A|A|AA|A|A|A|A|AA|A|A|A|A|AA|A|A|A||A|A|AA|A|A|A|A|AA|A|A|A|A|AA|A|A|A"...
--> tests/ui/filter-recursion.rs:4:19
|
4 | #[template(path = "filter-recursion.html")]

View File

@ -1,6 +1,6 @@
error: invalid escaper `latex` for `escape` filter. The available extensions are: "", "askama", "htm", "html", "j2", "jinja", "jinja2", "md", "none", "rinja", "svg", "txt", "xml", "yml"
--> LocalEscaper.html:1:38
"text|escape(\"latex\")}}`."
--> LocalEscaper.html:1:42
"|escape(\"latex\")}}`."
--> tests/ui/no-such-escaper.rs:6:14
|
6 | source = r#"In LaTeX you write `{{text}}` like `{{text|escape("latex")}}`."#,

View File

@ -1,6 +1,6 @@
error: `length` argument is missing when calling `truncate` filter; its arguments are: (length)
--> NoArgument.html:1:3
"text | truncate }}"
--> NoArgument.html:1:8
"| truncate }}"
--> tests/ui/truncate.rs:4:21
|
4 | #[template(source = r#"{{ text | truncate }}"#, ext = "html")]

View File

@ -1,14 +1,14 @@
error: `value` filter expects one generic, found 0
--> A.html:1:18
"\"a\"|value %}{% endif %}"
--> A.html:1:21
"|value %}{% endif %}"
--> tests/ui/values.rs:6:14
|
6 | source = r#"{% if let Ok(x) = "a"|value %}{% endif %}"#,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `value` filter expects one generic, found 2
--> B.html:1:18
"\"a\"|value::<u8, u8> %}{% endif %}"
--> B.html:1:21
"|value::<u8, u8> %}{% endif %}"
--> tests/ui/values.rs:13:14
|
13 | source = r#"{% if let Ok(x) = "a"|value::<u8, u8> %}{% endif %}"#,