Reduce usage of last statement spans in proc-macros #5092
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This excludes the initial let statement of the proc-macro expansion from receiving the last statement spans to aid completions in rust-analyzer. The current span confuses rust-analyzer as it will map the tail expression tokens to the let keyword (as this is the first token it finds with the same span) which currently breaks completions. This commit should not degrade the initial intent of the span reusages, as the type mismatch parts are still spanned appropriately.
Motivation
R-a is currently pretty terrible with spans, but needs them for proper usage of features in proc-macros, for example it uses them for figuring out where to analyse surrounding context for completions. More importantly it uses them to figure out what tokens to remove after fixing up syntax errors. Tokio's usage of the trailing expression span confuses r-a though, as all the tokens the proc-macro emits receive the span making r-a think they are partial part of the synthetic syntax it created to fix up a broken syntax tree removing them from the output.
Now this is obviously a bug in r-a, unfortunately its gonna take a while until that is gonna be fixed in r-a (as we need to rewrite our token mapping infra completely), hence this PR. If this is not something you wish to merge, that is fine as this basically only works around a very few cases of completions breaking in r-a (wherever broken syntax is typed basically), but I figured I could put the patch out given I already wrote it to test things out. See rust-lang/rust-analyzer#13355 for a lengthy discussion, and rust-lang/rust-analyzer#13388 for the fixup breakage.
Solution
The solution is simple due to technical reasons of how r-a's completion work, but if we exclude the initial let statement that re-uses the actual body, the tokens preceding the body will never be removed and thus won't mess up the ranges allowing r-a's completion to work properly with it. This does not degrade the diagnostics improvement that sparked the re-use of spans in the first place, as the type mismatches come from the final return expression, not the let statement. (Though I might be wrong, maybe there are certain cases where a diagnostic would come from the let statement?)