-
Notifications
You must be signed in to change notification settings - Fork 1.8k
ssr: Allow replacing expressions with statements #7147
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
Conversation
Adjusting `grammar::fragments::stmt` to Optional or Yes will break original functionality and tests.
Now that statements can be matched and replaced (rust-lang#6587) some usecases require expressions to be replaced with statements as well. This happens when something that can ambiguously be an expression or statement like `if` and loop blocks appear in the last position of a block, as trailing expression. In this case a replacement pattern of the form `if foo(){$a();}==>>$a();` will only substitute `if` blocks in the list of statements but not if they (implicitly) end up in the trailing expression, where they are not wrapped by an EXPR_STMT (but the pattern and template are, as parsing only succeeds for the `stmt ==>> stmt` case). Instead of adding two rules that match an expression - and emit duplicate matching errors - allow the template for expressions to be a statement if it fails to parse as an expression.
bors d=davidlattimore |
✌️ davidlattimore can now approve this pull request. To approve and merge a pull request, simply reply with |
Interesting. What happens if the search pattern matches somewhere a statement isn't valid? In this case the search pattern evaluates to the |
@davidlattimore The pattern in the tests To answer your question there's nothing in place preventing users from adding or removing semicolons to make resulting code invalid, or replace expressions with something nonsensical entirely like functions or struct definitions. Don't know if we need/want to impose such limits though, in the end it is the user specifying exactly what they want to replace. Other than that it's hard to come up with plausible test cases where this would perform an undesired change - they must exist and it'd be great to cover them. I haven't invested the time to check a potential implementation that limits such replacement to trailing block expressions only, but it already sounds complicated and error prone :) |
bors r+ |
Depends on #6587
Until that is merged, the diff is https://github.com/MarijnS95/rust-analyzer/compare/stmt..replace-expr-with-stmt
Now that statements can be matched and replaced (#6587) some usecases require expressions to be replaced with statements as well. This happens when something that can ambiguously be an expression or statement like
if
and loop blocks appear in the last position of a block, as trailing expression. In this case a replacement pattern of the formif foo(){$a();}==>>$a();
will only substituteif
blocks in the list of statements but not if they (implicitly) end up in the trailing expression, where they are not wrapped by an EXPR_STMT (but the pattern and template are, as parsing only succeeds for thestmt ==>> stmt
case).Instead of adding two rules that match an expression - and emit duplicate matching errors - allow the template for expressions to be a statement if it fails to parse as an expression.
Another gross change that does not seem to break any tests currently, but perhaps a safeguard should be added to only allow this kind of replacement in blocks by "pushing" the replacement template to the statement list and clearing the trailing expression?
CC @davidlattimore