-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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::Span::len and subspan #53930
Conversation
r=me if @alexcrichton has no concerns I'm not entirely sure what is the idiomatic naming choice between |
cc @eddyb |
Seems like a plausible API! I think this could definitely work for things like spans of string literals, but how does this work for spans of On another API note, does this handle pointing a byte position to the middle of a multibyte unicode character? Or would that perhaps cause an ICE later down the line? |
I would suspect it does. Frankly, I don't think we should expose any notion of "bytes" here. The fact that I'm seeing two problems here: not having access to the |
@dtolnay I prefer that but ideally it wouldn't be doing span manipulation at all. But also, let's say someone creates a |
IMO, it would be quite reasonable to restrict |
I started adding a But I realized that even when converting from internal |
We should probably just bite the bullet and keep track of the original delimiter token spans. |
I added this to #53902. Let me know if this is what you had in mind. Also @petrochenkov I see the confused reaction, let me know if you have concerns about that approach. |
☔ The latest upstream changes (presumably #53902) made this pull request unmergeable. Please resolve the merge conflicts. |
Before this addition, every delimited group like (...) [...] {...} has only a single Span that covers the full source location from opening delimiter to closing delimiter. This makes it impossible for a procedural macro to trigger an error pointing to just the opening or closing delimiter. The Rust compiler does not seem to have the same limitation: mod m { type T = } error: expected type, found `}` --> src/main.rs:3:1 | 3 | } | ^ On that same input, a procedural macro would be forced to trigger the error on the last token inside the block, on the entire block, or on the next token after the block, none of which is really what you want for an error like above. This commit adds span.len() and span.subspan(range) through which we can slice a span to point to some range of its original bytes. Relevant to Syn as we implement real error messages for when parsing fails in a procedural macro.
Rebased on #53902, but closing because #53902 is sufficient for my use case so someone else is going to need to drive this change. @petrochenkov's comment in #53902 (comment) for context:
|
Before this addition, every delimited group like
(
...)
[
...]
{
...}
has only a single Span that covers the full source location from opening delimiter to closing delimiter. This makes it impossible for a procedural macro to trigger an error pointing to just the opening or closing delimiter. The Rust compiler does not seem to have the same limitation:On that same input, a procedural macro would be forced to trigger the error on the last token inside the block, on the entire block, or on the next token after the block, none of which is really what you want for an error like above.
This commit adds
span.len()
andspan.subspan(range)
through which we can slice a span to point to some range of its original bytes.For example in the following line of source code the span of the opening parenthesis would be
.subspan(..1)
of the span of the parenthesis token, and the erroneous format specifier would be.subspan(9..12)
of the span of the string literal token.Relevant to Syn as we implement real error messages for when parsing fails in a procedural macro: dtolnay/syn#476.
Fixes #48187.
r? @petrochenkov
cc @alexcrichton