fix: Insert spaces when inlining a function defined in a macro.
@@ -7,7 +7,7 @@ use ide_db::{
imports::insert_use::remove_path_if_in_use_stmt,
path_transform::PathTransform,
search::{FileReference, SearchScope},
- syntax_helpers::node_ext::expr_as_name_ref,
+ syntax_helpers::{insert_whitespace_into_node::insert_ws_into, node_ext::expr_as_name_ref},
RootDatabase,
};
use itertools::{izip, Itertools};
@@ -301,7 +301,18 @@ fn inline(
params: &[(ast::Pat, Option<ast::Type>, hir::Param)],
CallInfo { node, arguments, generic_arg_list }: &CallInfo,
) -> ast::Expr {
- let body = fn_body.clone_for_update();
+ let body = if sema.hir_file_for(fn_body.syntax()).is_macro() {
+ cov_mark::hit!(inline_call_defined_in_macro);
+ if let Some(body) = ast::BlockExpr::cast(insert_ws_into(fn_body.syntax().clone())) {
+ body
+ } else {
+ // FIXME(zachs18): I believe this should be unreachable,
+ // since insert_ws_into shouldn't change the kind of the SyntaxNode.
+ fn_body.clone_for_update()
+ }
+ } else {
+ fn_body.clone_for_update()
+ };
let usages_for_locals = |local| {
Definition::Local(local)
.usages(sema)
@@ -1144,6 +1155,41 @@ fn bar() -> u32 {
x
}) + foo()
}
+"#,
+ )
+ }
+
+ #[test]
+ fn inline_call_defined_in_macro() {
+ cov_mark::check!(inline_call_defined_in_macro);
+ check_assist(
+ inline_call,
+ r#"
+macro_rules! define_foo {
+ () => { fn foo() -> u32 {
+ let x = 0;
+ x
+ } };
+}
+define_foo!();
+fn bar() -> u32 {
+ foo$0()
+}
+"#,
+ r#"
+macro_rules! define_foo {
+ () => { fn foo() -> u32 {
+ let x = 0;
+ x
+ } };
+}
+define_foo!();
+fn bar() -> u32 {
+ {
+ let x = 0;
+ x
+ }
+}
"#,
)
}
