Skip to content

Commit dafbe69

Browse files
committed
Wrap inlined closures in parens when inlined in an expression in inline_call
1 parent 2579dc6 commit dafbe69

File tree

3 files changed

+68
-8
lines changed

3 files changed

+68
-8
lines changed

crates/ide_assists/src/handlers/inline_call.rs

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ use crate::{
1414

1515
// Assist: inline_call
1616
//
17-
// Inlines a function or method body.
17+
// Inlines a function or method body creating a `let` statement per parameter unless the parameter
18+
// can be inlined. The parameter will be inlined either if it the supplied argument is a simple local
19+
// or if the parameter is only accessed inside the function body once.
1820
//
1921
// ```
2022
// # //- minicore: option
@@ -132,7 +134,7 @@ pub(crate) fn inline_(
132134
.covering_element(range)
133135
.ancestors()
134136
.nth(3)
135-
.filter(|it| ast::PathExpr::can_cast(it.kind())),
137+
.and_then(ast::PathExpr::cast),
136138
_ => None,
137139
})
138140
.collect::<Option<Vec<_>>>()
@@ -158,7 +160,14 @@ pub(crate) fn inline_(
158160
match &*usages {
159161
// inline single use parameters
160162
[usage] => {
161-
ted::replace(usage, expr.syntax().clone_for_update());
163+
let expr = if matches!(expr, ast::Expr::ClosureExpr(_))
164+
&& usage.syntax().parent().and_then(ast::Expr::cast).is_some()
165+
{
166+
make::expr_paren(expr)
167+
} else {
168+
expr
169+
};
170+
ted::replace(usage.syntax(), expr.syntax().clone_for_update());
162171
}
163172
// inline parameters whose expression is a simple local reference
164173
[_, ..]
@@ -168,7 +177,7 @@ pub(crate) fn inline_(
168177
) =>
169178
{
170179
usages.into_iter().for_each(|usage| {
171-
ted::replace(usage, &expr.syntax().clone_for_update());
180+
ted::replace(usage.syntax(), &expr.syntax().clone_for_update());
172181
});
173182
}
174183
// cant inline, emit a let statement
@@ -535,6 +544,56 @@ impl Foo {
535544
};
536545
}
537546
}
547+
"#,
548+
);
549+
}
550+
551+
#[test]
552+
fn wraps_closure_in_paren() {
553+
check_assist(
554+
inline_call,
555+
r#"
556+
fn foo(x: fn()) {
557+
x();
558+
}
559+
560+
fn main() {
561+
foo$0(|| {})
562+
}
563+
"#,
564+
r#"
565+
fn foo(x: fn()) {
566+
x();
567+
}
568+
569+
fn main() {
570+
{
571+
(|| {})();
572+
}
573+
}
574+
"#,
575+
);
576+
check_assist(
577+
inline_call,
578+
r#"
579+
fn foo(x: fn()) {
580+
x();
581+
}
582+
583+
fn main() {
584+
foo$0(main)
585+
}
586+
"#,
587+
r#"
588+
fn foo(x: fn()) {
589+
x();
590+
}
591+
592+
fn main() {
593+
{
594+
main();
595+
}
596+
}
538597
"#,
539598
);
540599
}

crates/ide_db/src/helpers/insert_use.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//! Handle syntactic aspects of inserting a new `use`.
2+
#[cfg(test)]
3+
mod tests;
4+
25
use std::cmp::Ordering;
36

47
use hir::Semantics;
@@ -378,5 +381,3 @@ fn is_inner_comment(token: SyntaxToken) -> bool {
378381
ast::Comment::cast(token).and_then(|comment| comment.kind().doc)
379382
== Some(ast::CommentPlacement::Inner)
380383
}
381-
#[cfg(test)]
382-
mod tests;

crates/ide_db/src/helpers/insert_use/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn foo() {$0}
1414
r#"
1515
#[cfg(test)]
1616
fn foo() {
17-
use bar::Bar;
17+
use bar::Bar;
1818
}
1919
"#,
2020
ImportGranularity::Crate,
@@ -32,7 +32,7 @@ const FOO: Bar = {$0};
3232
r#"
3333
#[cfg(test)]
3434
const FOO: Bar = {
35-
use bar::Bar;
35+
use bar::Bar;
3636
};
3737
"#,
3838
ImportGranularity::Crate,

0 commit comments

Comments
 (0)