Skip to content

Commit 50d6f18

Browse files
authored
Merge pull request #19588 from Hmikihiro/ext_func_module
fix: `Extract into` function include inline variable in fmt macro
2 parents 94f984f + 28e34c8 commit 50d6f18

File tree

1 file changed

+71
-14
lines changed

1 file changed

+71
-14
lines changed

crates/ide-assists/src/handlers/extract_function.rs

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -797,15 +797,21 @@ impl FunctionBody {
797797
) -> (FxIndexSet<Local>, Option<ast::SelfParam>) {
798798
let mut self_param = None;
799799
let mut res = FxIndexSet::default();
800-
let mut add_name_if_local = |name_ref: Option<_>| {
801-
let local_ref =
802-
match name_ref.and_then(|name_ref| NameRefClass::classify(sema, &name_ref)) {
803-
Some(
804-
NameRefClass::Definition(Definition::Local(local_ref), _)
805-
| NameRefClass::FieldShorthand { local_ref, field_ref: _, adt_subst: _ },
806-
) => local_ref,
807-
_ => return,
808-
};
800+
801+
fn local_from_name_ref(
802+
sema: &Semantics<'_, RootDatabase>,
803+
name_ref: ast::NameRef,
804+
) -> Option<hir::Local> {
805+
match NameRefClass::classify(sema, &name_ref) {
806+
Some(
807+
NameRefClass::Definition(Definition::Local(local_ref), _)
808+
| NameRefClass::FieldShorthand { local_ref, field_ref: _, adt_subst: _ },
809+
) => Some(local_ref),
810+
_ => None,
811+
}
812+
}
813+
814+
let mut add_name_if_local = |local_ref: Local| {
809815
let InFile { file_id, value } = local_ref.primary_source(sema.db).source;
810816
// locals defined inside macros are not relevant to us
811817
if !file_id.is_macro() {
@@ -821,13 +827,20 @@ impl FunctionBody {
821827
};
822828
self.walk_expr(&mut |expr| match expr {
823829
ast::Expr::PathExpr(path_expr) => {
824-
add_name_if_local(path_expr.path().and_then(|it| it.as_single_name_ref()))
830+
if let Some(local) = path_expr
831+
.path()
832+
.and_then(|it| it.as_single_name_ref())
833+
.and_then(|name_ref| local_from_name_ref(sema, name_ref))
834+
{
835+
add_name_if_local(local);
836+
}
825837
}
826838
ast::Expr::ClosureExpr(closure_expr) => {
827839
if let Some(body) = closure_expr.body() {
828840
body.syntax()
829841
.descendants()
830-
.map(ast::NameRef::cast)
842+
.filter_map(ast::NameRef::cast)
843+
.filter_map(|name_ref| local_from_name_ref(sema, name_ref))
831844
.for_each(&mut add_name_if_local);
832845
}
833846
}
@@ -836,9 +849,31 @@ impl FunctionBody {
836849
tt.syntax()
837850
.descendants_with_tokens()
838851
.filter_map(SyntaxElement::into_token)
839-
.filter(|it| matches!(it.kind(), SyntaxKind::IDENT | T![self]))
840-
.flat_map(|t| sema.descend_into_macros_exact(t))
841-
.for_each(|t| add_name_if_local(t.parent().and_then(ast::NameRef::cast)));
852+
.filter(|it| {
853+
matches!(it.kind(), SyntaxKind::STRING | SyntaxKind::IDENT | T![self])
854+
})
855+
.for_each(|t| {
856+
if ast::String::can_cast(t.kind()) {
857+
if let Some(parts) =
858+
ast::String::cast(t).and_then(|s| sema.as_format_args_parts(&s))
859+
{
860+
parts
861+
.into_iter()
862+
.filter_map(|(_, value)| value.and_then(|it| it.left()))
863+
.filter_map(|path| match path {
864+
PathResolution::Local(local) => Some(local),
865+
_ => None,
866+
})
867+
.for_each(&mut add_name_if_local);
868+
}
869+
} else {
870+
sema.descend_into_macros_exact(t)
871+
.into_iter()
872+
.filter_map(|t| t.parent().and_then(ast::NameRef::cast))
873+
.filter_map(|name_ref| local_from_name_ref(sema, name_ref))
874+
.for_each(&mut add_name_if_local);
875+
}
876+
});
842877
}
843878
}
844879
_ => (),
@@ -6130,6 +6165,28 @@ fn $0fun_name(a: i32, b: i32, c: i32, x: i32) -> i32 {
61306165
);
61316166
}
61326167

6168+
#[test]
6169+
fn fmt_macro_argument() {
6170+
check_assist(
6171+
extract_function,
6172+
r#"
6173+
//- minicore: fmt
6174+
fn existing(a: i32, b: i32, c: i32) {
6175+
$0print!("{a}{}{}", b, "{c}");$0
6176+
}
6177+
"#,
6178+
r#"
6179+
fn existing(a: i32, b: i32, c: i32) {
6180+
fun_name(a, b);
6181+
}
6182+
6183+
fn $0fun_name(a: i32, b: i32) {
6184+
print!("{a}{}{}", b, "{c}");
6185+
}
6186+
"#,
6187+
);
6188+
}
6189+
61336190
#[test]
61346191
fn in_left_curly_is_not_applicable() {
61356192
cov_mark::check!(extract_function_in_braces_is_not_applicable);

0 commit comments

Comments
 (0)