Skip to content
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

Improve syntax fixup for proc macros #12777

Open
2 tasks
flodiebold opened this issue Jul 16, 2022 · 1 comment
Open
2 tasks

Improve syntax fixup for proc macros #12777

flodiebold opened this issue Jul 16, 2022 · 1 comment
Assignees
Labels
A-macro macro expansion C-feature Category: feature request E-easy E-has-instructions Issue has some instructions and pointers to code to get started

Comments

@flodiebold
Copy link
Member

flodiebold commented Jul 16, 2022

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:

  • incomplete paths like foo::
  • incomplete flow control keywords like loop without a block, for missing its various components etc.
@flodiebold flodiebold added E-easy E-has-instructions Issue has some instructions and pointers to code to get started A-macro macro expansion C-feature Category: feature request labels Jul 16, 2022
bors added a commit that referenced this issue Aug 2, 2022
Add syntax fixup for while loops

Part of #12777

This is a first iteration to gather some feedback. In particular I'm not sure if the curly braces should be added here, but I couldn't get the test to work without them. Any hints welcome!
@fprasx
Copy link
Contributor

fprasx commented Aug 3, 2022

@rustbot claim

bors added a commit that referenced this issue Aug 8, 2022
Add fixups for incomplete in proc-macros

Partially implements #12777.

Added support for for loops and match statements.

I couldn't do paths like `crate::foo::` as I wasn't able to add `SyntheticTokens` to the end of `foo::`, they always ended up after `crate::`

This is my first contribution so please don't be shy about letting me know if I've done anything wrong!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macro macro expansion C-feature Category: feature request E-easy E-has-instructions Issue has some instructions and pointers to code to get started
Projects
None yet
Development

No branches or pull requests

2 participants