rust-lang / rust-lang/rust-analyzer
Proc-macros that re-use input spans break our syntax fixup
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.9k
- Forks
- 2.2k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 72
Description

#[tokio::main]
async fn main() {
main.
}
gets expanded to
fn main(){
{
main.
}[()]{
tokio::runtime::Builder::new_multi_thread()()()()()
}
}
while ideally it should be
fn main() {
let body = async { main. };
#[allow(clippy::expect_used, clippy::diverging_sub_expression)]
{
return tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed building the Runtime")
.block_on(body);
}
}
tokio-macros version 1.8.0
This happens because the tokio macro is applying the span of the final expression of the block to all its extra tokens that it is outputting, so our syntax fixup (given its based on the token id of tokens, and token ids being our current span) completely obliterates the output in this case.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the example with tokio-macros 1.8.0 and compare the expanded output with the expected expansion. Trace syntax fixup's use of token IDs and spans, focusing on proc-macro output whose extra tokens reuse the final expression's span. Done means the generated async-main expansion is preserved instead of being obliterated by syntax fixup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100