Skip to content

Commit 339a186

Browse files
committed
Auto merge of rust-lang#12110 - jonas-schievink:inline-self-type, r=jonas-schievink
feat: Make "inline type alias" work for `Self` Fixes rust-lang/rust-analyzer#12109
2 parents d382e24 + c702712 commit 339a186

File tree

1 file changed

+102
-17
lines changed

1 file changed

+102
-17
lines changed

crates/ide_assists/src/handlers/inline_type_alias.rs

+102-17
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// - "inline_alias_to_users" assist #10881.
44
// - Remove unused aliases if there are no longer any users, see inline_call.rs.
55

6-
use hir::PathResolution;
6+
use hir::{HasSource, PathResolution};
77
use itertools::Itertools;
88
use std::collections::HashMap;
99
use syntax::{
@@ -41,31 +41,48 @@ use crate::{
4141
// }
4242
// ```
4343
pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
44-
let alias_instance = ctx.find_node_at_offset::<ast::PathType>()?;
45-
let alias = get_type_alias(&ctx, &alias_instance)?;
46-
let concrete_type = alias.ty()?;
47-
4844
enum Replacement {
4945
Generic { lifetime_map: LifetimeMap, const_and_type_map: ConstAndTypeMap },
5046
Plain,
5147
}
5248

53-
let replacement = if let Some(alias_generics) = alias.generic_param_list() {
54-
if alias_generics.generic_params().next().is_none() {
55-
cov_mark::hit!(no_generics_params);
56-
return None;
49+
let alias_instance = ctx.find_node_at_offset::<ast::PathType>()?;
50+
let concrete_type;
51+
let replacement;
52+
match alias_instance.path()?.as_single_name_ref() {
53+
Some(nameref) if nameref.Self_token().is_some() => {
54+
match ctx.sema.resolve_path(&alias_instance.path()?)? {
55+
PathResolution::SelfType(imp) => {
56+
concrete_type = imp.source(ctx.db())?.value.self_ty()?;
57+
}
58+
// FIXME: should also work in ADT definitions
59+
_ => return None,
60+
}
61+
62+
replacement = Replacement::Plain;
5763
}
64+
_ => {
65+
let alias = get_type_alias(&ctx, &alias_instance)?;
66+
concrete_type = alias.ty()?;
67+
68+
replacement = if let Some(alias_generics) = alias.generic_param_list() {
69+
if alias_generics.generic_params().next().is_none() {
70+
cov_mark::hit!(no_generics_params);
71+
return None;
72+
}
5873

59-
let instance_args =
60-
alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
74+
let instance_args =
75+
alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
6176

62-
Replacement::Generic {
63-
lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
64-
const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
77+
Replacement::Generic {
78+
lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
79+
const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
80+
}
81+
} else {
82+
Replacement::Plain
83+
};
6584
}
66-
} else {
67-
Replacement::Plain
68-
};
85+
}
6986

7087
let target = alias_instance.syntax().text_range();
7188

@@ -752,6 +769,74 @@ mod foo {
752769
fn main() {
753770
let a: String;
754771
}
772+
"#,
773+
);
774+
}
775+
776+
#[test]
777+
fn inline_self_type() {
778+
check_assist(
779+
inline_type_alias,
780+
r#"
781+
struct Strukt;
782+
783+
impl Strukt {
784+
fn new() -> Self$0 {}
785+
}
786+
"#,
787+
r#"
788+
struct Strukt;
789+
790+
impl Strukt {
791+
fn new() -> Strukt {}
792+
}
793+
"#,
794+
);
795+
check_assist(
796+
inline_type_alias,
797+
r#"
798+
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
799+
800+
impl<T, const C: usize> Strukt<'_, T, C> {
801+
fn new() -> Self$0 {}
802+
}
803+
"#,
804+
r#"
805+
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
806+
807+
impl<T, const C: usize> Strukt<'_, T, C> {
808+
fn new() -> Strukt<'_, T, C> {}
809+
}
810+
"#,
811+
);
812+
check_assist(
813+
inline_type_alias,
814+
r#"
815+
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
816+
817+
trait Tr<'b, T> {}
818+
819+
impl<T, const C: usize> Tr<'static, u8> for Strukt<'_, T, C> {
820+
fn new() -> Self$0 {}
821+
}
822+
"#,
823+
r#"
824+
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
825+
826+
trait Tr<'b, T> {}
827+
828+
impl<T, const C: usize> Tr<'static, u8> for Strukt<'_, T, C> {
829+
fn new() -> Strukt<'_, T, C> {}
830+
}
831+
"#,
832+
);
833+
834+
check_assist_not_applicable(
835+
inline_type_alias,
836+
r#"
837+
trait Tr {
838+
fn new() -> Self$0;
839+
}
755840
"#,
756841
);
757842
}

0 commit comments

Comments
 (0)