diff --git a/crates/ide_assists/src/handlers/inline_call.rs b/crates/ide_assists/src/handlers/inline_call.rs index 2059a7472d..f6840a27b3 100644 --- a/crates/ide_assists/src/handlers/inline_call.rs +++ b/crates/ide_assists/src/handlers/inline_call.rs @@ -14,7 +14,9 @@ use crate::{ // Assist: inline_call // -// Inlines a function or method body. +// Inlines a function or method body creating a `let` statement per parameter unless the parameter +// can be inlined. The parameter will be inlined either if it the supplied argument is a simple local +// or if the parameter is only accessed inside the function body once. // // ``` // # //- minicore: option @@ -132,7 +134,7 @@ pub(crate) fn inline_( .covering_element(range) .ancestors() .nth(3) - .filter(|it| ast::PathExpr::can_cast(it.kind())), + .and_then(ast::PathExpr::cast), _ => None, }) .collect::>>() @@ -158,7 +160,14 @@ pub(crate) fn inline_( match &*usages { // inline single use parameters [usage] => { - ted::replace(usage, expr.syntax().clone_for_update()); + let expr = if matches!(expr, ast::Expr::ClosureExpr(_)) + && usage.syntax().parent().and_then(ast::Expr::cast).is_some() + { + make::expr_paren(expr) + } else { + expr + }; + ted::replace(usage.syntax(), expr.syntax().clone_for_update()); } // inline parameters whose expression is a simple local reference [_, ..] @@ -168,7 +177,7 @@ pub(crate) fn inline_( ) => { usages.into_iter().for_each(|usage| { - ted::replace(usage, &expr.syntax().clone_for_update()); + ted::replace(usage.syntax(), &expr.syntax().clone_for_update()); }); } // cant inline, emit a let statement @@ -535,6 +544,56 @@ impl Foo { }; } } +"#, + ); + } + + #[test] + fn wraps_closure_in_paren() { + check_assist( + inline_call, + r#" +fn foo(x: fn()) { + x(); +} + +fn main() { + foo$0(|| {}) +} +"#, + r#" +fn foo(x: fn()) { + x(); +} + +fn main() { + { + (|| {})(); + } +} +"#, + ); + check_assist( + inline_call, + r#" +fn foo(x: fn()) { + x(); +} + +fn main() { + foo$0(main) +} +"#, + r#" +fn foo(x: fn()) { + x(); +} + +fn main() { + { + main(); + } +} "#, ); } diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index 4e12fe1507..e16021c82f 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs @@ -1,4 +1,7 @@ //! Handle syntactic aspects of inserting a new `use`. +#[cfg(test)] +mod tests; + use std::cmp::Ordering; use hir::Semantics; @@ -378,5 +381,3 @@ fn is_inner_comment(token: SyntaxToken) -> bool { ast::Comment::cast(token).and_then(|comment| comment.kind().doc) == Some(ast::CommentPlacement::Inner) } -#[cfg(test)] -mod tests; diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index 2e0153a180..c5420f4679 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs @@ -14,7 +14,7 @@ fn foo() {$0} r#" #[cfg(test)] fn foo() { -use bar::Bar; + use bar::Bar; } "#, ImportGranularity::Crate, @@ -32,7 +32,7 @@ const FOO: Bar = {$0}; r#" #[cfg(test)] const FOO: Bar = { -use bar::Bar; + use bar::Bar; }; "#, ImportGranularity::Crate,