From b80ca3f35ef488cccc4af00ea1b0571058eb025f Mon Sep 17 00:00:00 2001 From: Aditya-PS-05 Date: Thu, 20 Nov 2025 04:01:14 +0530 Subject: [PATCH] fix: never remove parens from prefix ops with valueless return/break/continue --- .../src/handlers/remove_parentheses.rs | 24 +++++++++++++++++++ crates/syntax/src/ast/prec.rs | 6 +++++ 2 files changed, 30 insertions(+) diff --git a/crates/ide-assists/src/handlers/remove_parentheses.rs b/crates/ide-assists/src/handlers/remove_parentheses.rs index d514c1c29158..fb051e5b5780 100644 --- a/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -162,6 +162,30 @@ mod tests { check_assist_not_applicable(remove_parentheses, r#"fn f() { if $0(return) {} }"#); } + #[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( diff --git a/crates/syntax/src/ast/prec.rs b/crates/syntax/src/ast/prec.rs index 1364adb187fc..2e58f7be2925 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()