mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 01:17:27 +00:00
Auto merge of #12877 - zachs18:inline-def-in-macro, r=zachs18
fix: Insert spaces when inlining a function defined in a macro. (partially) fixes #12860. This PR (only) addresses the whitespace issue when inlining functions defined in macros. Additionally, the indentation/spacing is not ideal, but works, e.g. ```rs macro_rules! define_function { () => { fn test_function_macro() { if let Some(3) = 3i32.checked_add(0) { println!("3 + 0 == 3"); } } }; } define_function!(); fn main() { test_function_macro(); } // previously became // ... fn main() { ifletSome(3)=3i32.checked_add(0){println!("3 + 0 == 3");}; } // now becomes // ... fn main() { if let Some(3) = 3i32.checked_add(0){ println!("3 + 0 == 3"); }; } ``` The `self` -> `this` problem[^this] is (probably?) a separate problem that I am also looking into. [^this]: As mentioned in [my comment on the above issue](https://github.com/rust-lang/rust-analyzer/issues/12860#issuecomment-1193231766), inlining a method defined in a macro does not properly replace `self` with the new local `this`.
This commit is contained in:
commit
c2eebd7a50
1 changed files with 46 additions and 2 deletions
|
@ -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,16 @@ 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 {
|
||||
fn_body.clone_for_update()
|
||||
}
|
||||
} else {
|
||||
fn_body.clone_for_update()
|
||||
};
|
||||
let usages_for_locals = |local| {
|
||||
Definition::Local(local)
|
||||
.usages(sema)
|
||||
|
@ -1144,6 +1153,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
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue