Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21092 from Aditya-PS-05/fix/remove-parens-prefix-operators
fix: never remove parens from prefix ops with valueless return/break/continue
Shoyu Vanilla (Flint) 5 months ago
parent 35c0661 · parent b80ca3f · commit 8b45966
-rw-r--r--crates/ide-assists/src/handlers/remove_parentheses.rs24
-rw-r--r--crates/syntax/src/ast/prec.rs6
2 files changed, 30 insertions, 0 deletions
diff --git a/crates/ide-assists/src/handlers/remove_parentheses.rs b/crates/ide-assists/src/handlers/remove_parentheses.rs
index d514c1c291..fb051e5b57 100644
--- a/crates/ide-assists/src/handlers/remove_parentheses.rs
+++ b/crates/ide-assists/src/handlers/remove_parentheses.rs
@@ -163,6 +163,30 @@ mod tests {
}
#[test]
+ fn remove_parens_prefix_with_return_no_value() {
+ // removing `()` from !(return) would make `!return` which is invalid syntax
+ check_assist_not_applicable(
+ remove_parentheses,
+ r#"fn main() { let _x = true && !$0(return) || true; }"#,
+ );
+ check_assist_not_applicable(remove_parentheses, r#"fn f() { !$0(return) }"#);
+ check_assist_not_applicable(remove_parentheses, r#"fn f() { !$0(break) }"#);
+ check_assist_not_applicable(remove_parentheses, r#"fn f() { !$0(continue) }"#);
+
+ // Binary operators should still allow removal
+ check_assist(
+ remove_parentheses,
+ r#"fn f() { true || $0(return) }"#,
+ r#"fn f() { true || return }"#,
+ );
+ check_assist(
+ remove_parentheses,
+ r#"fn f() { cond && $0(return) }"#,
+ r#"fn f() { cond && return }"#,
+ );
+ }
+
+ #[test]
fn remove_parens_return_with_value_followed_by_block() {
check_assist(
remove_parentheses,
diff --git a/crates/syntax/src/ast/prec.rs b/crates/syntax/src/ast/prec.rs
index 1364adb187..2e58f7be29 100644
--- a/crates/syntax/src/ast/prec.rs
+++ b/crates/syntax/src/ast/prec.rs
@@ -226,6 +226,12 @@ impl Expr {
return false;
}
+ // Special-case prefix operators with return/break/etc without value
+ // e.g., `!(return)` - parentheses are necessary
+ if self.is_ret_like_with_no_value() && parent.is_prefix() {
+ return true;
+ }
+
if self.is_paren_like()
|| parent.is_paren_like()
|| self.is_prefix()