Skip to content

Commit ccc29b0

Browse files
extract_type_alias assist extracts inferred type when possible
When met with types with placeholders, this ensures this assist extracts the inferred type instead of the type with placeholders. For instance, when met with this code: ``` fn main() { let vec: Vec<_> = vec![4]; } ``` selecting Vec<_> and extracting an alias will now yield `Vec<i32>` instead of `Vec<_>`.
1 parent 615ea09 commit ccc29b0

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

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

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use either::Either;
2+
use hir::HirDisplay;
23
use ide_db::syntax_helpers::node_ext::walk_ty;
34
use syntax::{
45
ast::{self, AstNode, HasGenericArgs, HasGenericParams, HasName, edit::IndentLevel, make},
@@ -39,6 +40,15 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
3940
);
4041
let target = ty.syntax().text_range();
4142

43+
let resolved_ty = ctx.sema.resolve_type(&ty)?;
44+
let resolved_ty = if !resolved_ty.contains_unknown() {
45+
let module = ctx.sema.scope(ty.syntax())?.module();
46+
let resolved_ty = resolved_ty.display_source_code(ctx.db(), module.into(), false).ok()?;
47+
make::ty(&resolved_ty)
48+
} else {
49+
ty.clone()
50+
};
51+
4252
acc.add(
4353
AssistId::refactor_extract("extract_type_alias"),
4454
"Extract type as type alias",
@@ -72,7 +82,7 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
7282

7383
// Insert new alias
7484
let ty_alias =
75-
make::ty_alias(None, "Type", generic_params, None, None, Some((ty, None)))
85+
make::ty_alias(None, "Type", generic_params, None, None, Some((resolved_ty, None)))
7686
.clone_for_update();
7787

7888
if let Some(cap) = ctx.config.snippet_cap
@@ -391,4 +401,50 @@ where
391401
"#,
392402
);
393403
}
404+
405+
#[test]
406+
fn inferred_generic_type_parameter() {
407+
check_assist(
408+
extract_type_alias,
409+
r#"
410+
struct Wrap<T>(T);
411+
412+
fn main() {
413+
let wrap: $0Wrap<_>$0 = Wrap::<_>(3i32);
414+
}
415+
"#,
416+
r#"
417+
struct Wrap<T>(T);
418+
419+
type $0Type = Wrap<i32>;
420+
421+
fn main() {
422+
let wrap: Type = Wrap::<_>(3i32);
423+
}
424+
"#,
425+
)
426+
}
427+
428+
#[test]
429+
fn inferred_type() {
430+
check_assist(
431+
extract_type_alias,
432+
r#"
433+
struct Wrap<T>(T);
434+
435+
fn main() {
436+
let wrap: Wrap<$0_$0> = Wrap::<_>(3i32);
437+
}
438+
"#,
439+
r#"
440+
struct Wrap<T>(T);
441+
442+
type $0Type = i32;
443+
444+
fn main() {
445+
let wrap: Wrap<Type> = Wrap::<_>(3i32);
446+
}
447+
"#,
448+
)
449+
}
394450
}

0 commit comments

Comments
 (0)