Skip to content

Use Parser::[with_]span() to get byte range and use byte range for proc_macro::Span#571

Merged
Kijewski merged 6 commits intoaskama-rs:masterfrom
Kijewski:pr-span
Aug 19, 2025
Merged

Use Parser::[with_]span() to get byte range and use byte range for proc_macro::Span#571
Kijewski merged 6 commits intoaskama-rs:masterfrom
Kijewski:pr-span

Conversation

@Kijewski
Copy link
Copy Markdown
Member

@Kijewski Kijewski commented Aug 13, 2025

This PR includes the following changes:

  • Instead of taking an &str as a span, we use the byte range in the input string. With this change we don't have to track the lifetime of the input string, so <'a> got removed from WithSpan and Span. When tacking a subspan of a Literal, we need the byte range, not the text.
  • Calculating the byte range is done using winnow's LocatingStream::span(). Because of that change, almost every instance of parser.with_taken() was replaced with parser.with_span().
  • The byte range for Literal::subspan() is not the bytes in the unescaped string, but in the stored representation. E.g. in "a\u{62}c" the b is not at 1..2, but at 2..8. We use literal-escaper to manually interpret/unescape the input string, because with LitStr::value() we would not be able to tell "abc", "a\u{62}c", and r###"abc"### apart.
  • Instead of manually passing the State and/or nesting Level to recursive calls in the parser, we use winnow's StatefulStream. This means that most instances of (|i: &mut _| p(i, s)).parse_next(i)? could be replaced with p.parse_next(i)?.

Comment thread askama_derive/src/input.rs Fixed
Comment thread askama_derive/src/input.rs Fixed
@Kijewski

This comment was marked as resolved.

Comment thread askama_derive/src/spans.rs Fixed
Comment thread askama_derive/src/spans.rs Fixed
@Kijewski
Copy link
Copy Markdown
Member Author

I copied the unescape implementation of literal-escaper, because it is (IMHO needlessly) msrv 1.89, and version 0.0.5 does not sound very stable. :)

Now, on nightly, the correct subspan in #[template(source = "..")] gets underlined even if the literal contains escape sequences.

@Kijewski Kijewski force-pushed the pr-span branch 3 times, most recently from 389f10d to b1da00e Compare August 15, 2025 23:25
Comment thread askama_derive/src/spans.rs Dismissed
@Kijewski Kijewski force-pushed the pr-span branch 5 times, most recently from 589c19a to 657e26b Compare August 16, 2025 11:31
Comment thread askama_derive/Cargo.toml Outdated
@Kijewski Kijewski force-pushed the pr-span branch 3 times, most recently from c294554 to 1e38a92 Compare August 17, 2025 00:19
@Kijewski
Copy link
Copy Markdown
Member Author

@GuillaumeGomez, I think it's ready to be reviewed. The spans for "code-in-doc" can be added in a subsequent PR. But take your time. The change is kinda big. 🤐

@@ -0,0 +1,185 @@
// The content of this file was copied and adapted from the project [`rustc-literal-escaper`] in
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is missing from rustc-literal-escaper that you needed to copy some parts of it? If some sub-parts can be useful, I can make them public.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing was missing, rustc-literal-escaper works fine! The part of rustc-literal-escaper we need is quite small. We copied other small function like path_clean::clean() and pathdiff::diff_paths(), too, instead of adding a dependency.

I don't like the use of NonZero<u8> instead of NonZeroU8, because it needlessly rises the MSRV to 1.89, and the version number 0.0.5 did not instill me with confidence. :) A 0.0.x version is effectively a pinned version, so we would have to release a new Askama version when a new rustc-literal-escaper is released, or downstream users would not get updates.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More than 100 lines of code seems a bit too much to me but considering how big the PR is, but we can rediscuss it later on, for now I just want this PR to be merged. :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to replace the copied code with a dependency once rustc-literal-escaper 0.1.0 was released! :)

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Went over the code, that's quite impressive. O.o

So at this point, I'm pretty sure I missed most of the important bits. Can you update the first comment to add a high-level overview of the changes here please for posterity?

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Thanks! Feel free to merge.

@Kijewski
Copy link
Copy Markdown
Member Author

Thank you! :)

@Kijewski Kijewski merged commit 8c02e48 into askama-rs:master Aug 19, 2025
51 checks passed
@Kijewski Kijewski deleted the pr-span branch August 19, 2025 15:41
@Kijewski Kijewski mentioned this pull request Aug 18, 2025
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

Successfully merging this pull request may close these issues.

3 participants