Skip to content

Commit b331c52

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 eb5401e commit b331c52

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

src/tools/rust-analyzer/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)