To make completion work inside attribute proc macros like #[tokio::main], we take incomplete code inside the attribute input and 'fix it up' to make sure the proc macro can parse it. This already works pretty well in the common cases, but I think there are lots of edge cases missing. This usually results in completion not working inside the proc macro for a moment while typing something, and then working again once one has typed a more complete expression, so I think people are unlikely to report cases like this and will just chalk it up to "rust-analyzer being unreliable". So I think it's worth to look for edge cases that are missing and add them.
Also, while it would be nice to have some more automatic / principled way to do this syntax fixup, any work adding more cases to the current code and extending the test suite will not be wasted; the test suite is really the most important part.
The syntax fixup code lives in the fixup module:
|
//! To make attribute macros work reliably when typing, we need to take care to |
|
//! fix up syntax errors in the code we're passing to them. |
|
use std::mem; |
New cases will need to be added to the big match_ast! in the fixup_syntax function:
As can be seen from the existing cases, this mostly consists of checking if some part of a node is missing and inserting a simple placeholder token or two (an identifier, or some missing punctuation).
For each case, a test case should be added at the end of the module. The tests look like this:
|
#[test] |
|
fn extraneous_comma() { |
|
check( |
|
r#" |
|
fn foo() { |
|
bar(,); |
|
} |
|
"#, |
|
expect![[r#" |
|
fn foo () {__ra_fixup ;} |
|
"#]], |
|
) |
|
} |
Test cases consist of the original incomplete code, and the "fixed up" code. The "fixed up" code can be automatically updated by running
UPDATE_EXPECT=1 cargo test -p hir-expand, and the tests also check the important conditions that 1. the fixed-up code is syntactically complete, and 2. the fixups can be reversed afterwards, so if these checks succeed, the fixup is working.
Here are some cases that I think we are missing currently:
To make completion work inside attribute proc macros like
#[tokio::main], we take incomplete code inside the attribute input and 'fix it up' to make sure the proc macro can parse it. This already works pretty well in the common cases, but I think there are lots of edge cases missing. This usually results in completion not working inside the proc macro for a moment while typing something, and then working again once one has typed a more complete expression, so I think people are unlikely to report cases like this and will just chalk it up to "rust-analyzer being unreliable". So I think it's worth to look for edge cases that are missing and add them.Also, while it would be nice to have some more automatic / principled way to do this syntax fixup, any work adding more cases to the current code and extending the test suite will not be wasted; the test suite is really the most important part.
The syntax fixup code lives in the
fixupmodule:rust-analyzer/crates/hir-expand/src/fixup.rs
Lines 1 to 3 in 96481b7
New cases will need to be added to the big
match_ast!in thefixup_syntaxfunction:rust-analyzer/crates/hir-expand/src/fixup.rs
Line 73 in 96481b7
As can be seen from the existing cases, this mostly consists of checking if some part of a node is missing and inserting a simple placeholder token or two (an identifier, or some missing punctuation).
For each case, a test case should be added at the end of the module. The tests look like this:
rust-analyzer/crates/hir-expand/src/fixup.rs
Lines 288 to 300 in 96481b7
Test cases consist of the original incomplete code, and the "fixed up" code. The "fixed up" code can be automatically updated by running
UPDATE_EXPECT=1 cargo test -p hir-expand, and the tests also check the important conditions that 1. the fixed-up code is syntactically complete, and 2. the fixups can be reversed afterwards, so if these checks succeed, the fixup is working.Here are some cases that I think we are missing currently:
foo::loopwithout a block,formissing its various components etc.