diff options
| author | bors <bors@rust-lang.org> | 2024-06-24 08:25:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-24 08:25:49 +0000 |
| commit | 1cd8bc0cf2e84207adf59165f5c433aebd142103 (patch) | |
| tree | a78eadc231d37899da42359cb7a0fd1371ba452f /src | |
| parent | f9a337cc881aba5f4acdc07dffc16a0bb76da99f (diff) | |
| parent | f1debd96e458542a484fd1d0d0b709c9d7516b7c (diff) | |
| download | rust-1cd8bc0cf2e84207adf59165f5c433aebd142103.tar.gz rust-1cd8bc0cf2e84207adf59165f5c433aebd142103.zip | |
Auto merge of #17471 - davidsemakula:fix-remove-parenthesis, r=Veykril
fix: don't remove parentheses for calls of function-like pointers that are members of a struct or union Fixes #17111
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs | 29 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs | 8 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs index 799d36be93e..f74fc261128 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -239,4 +239,33 @@ mod tests { check_assist_not_applicable(remove_parentheses, r#"fn f() { $0(return 2) + 2 }"#); } + + #[test] + fn remove_parens_indirect_calls() { + check_assist( + remove_parentheses, + r#"fn f(call: fn(usize), arg: usize) { $0(call)(arg); }"#, + r#"fn f(call: fn(usize), arg: usize) { call(arg); }"#, + ); + check_assist( + remove_parentheses, + r#"fn f<F>(call: F, arg: usize) where F: Fn(usize) { $0(call)(arg); }"#, + r#"fn f<F>(call: F, arg: usize) where F: Fn(usize) { call(arg); }"#, + ); + + // Parentheses are necessary when calling a function-like pointer that is a member of a struct or union. + check_assist_not_applicable( + remove_parentheses, + r#" +struct Foo<T> { + t: T, +} + +impl Foo<fn(usize)> { + fn foo(&self, arg: usize) { + $0(self.t)(arg); + } +}"#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index 9131cd2f179..28089ffb377 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -27,6 +27,14 @@ impl Expr { } fn needs_parens_in_expr(&self, parent: &Expr) -> bool { + // Parentheses are necessary when calling a function-like pointer that is a member of a struct or union + // (e.g. `(a.f)()`). + let is_parent_call_expr = matches!(parent, ast::Expr::CallExpr(_)); + let is_field_expr = matches!(self, ast::Expr::FieldExpr(_)); + if is_parent_call_expr && is_field_expr { + return true; + } + // Special-case block weirdness if parent.child_is_followed_by_a_block() { use Expr::*; |
