mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-04 04:39:16 +00:00
Auto merge of #12110 - jonas-schievink:inline-self-type, r=jonas-schievink
feat: Make "inline type alias" work for `Self` Fixes https://github.com/rust-lang/rust-analyzer/issues/12109
This commit is contained in:
commit
339a1867f4
@ -3,7 +3,7 @@
|
||||
// - "inline_alias_to_users" assist #10881.
|
||||
// - Remove unused aliases if there are no longer any users, see inline_call.rs.
|
||||
|
||||
use hir::PathResolution;
|
||||
use hir::{HasSource, PathResolution};
|
||||
use itertools::Itertools;
|
||||
use std::collections::HashMap;
|
||||
use syntax::{
|
||||
@ -41,31 +41,48 @@ use crate::{
|
||||
// }
|
||||
// ```
|
||||
pub(crate) fn inline_type_alias(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let alias_instance = ctx.find_node_at_offset::<ast::PathType>()?;
|
||||
let alias = get_type_alias(&ctx, &alias_instance)?;
|
||||
let concrete_type = alias.ty()?;
|
||||
|
||||
enum Replacement {
|
||||
Generic { lifetime_map: LifetimeMap, const_and_type_map: ConstAndTypeMap },
|
||||
Plain,
|
||||
}
|
||||
|
||||
let replacement = if let Some(alias_generics) = alias.generic_param_list() {
|
||||
if alias_generics.generic_params().next().is_none() {
|
||||
cov_mark::hit!(no_generics_params);
|
||||
return None;
|
||||
}
|
||||
let alias_instance = ctx.find_node_at_offset::<ast::PathType>()?;
|
||||
let concrete_type;
|
||||
let replacement;
|
||||
match alias_instance.path()?.as_single_name_ref() {
|
||||
Some(nameref) if nameref.Self_token().is_some() => {
|
||||
match ctx.sema.resolve_path(&alias_instance.path()?)? {
|
||||
PathResolution::SelfType(imp) => {
|
||||
concrete_type = imp.source(ctx.db())?.value.self_ty()?;
|
||||
}
|
||||
// FIXME: should also work in ADT definitions
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
let instance_args =
|
||||
alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
|
||||
|
||||
Replacement::Generic {
|
||||
lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
|
||||
const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
|
||||
replacement = Replacement::Plain;
|
||||
}
|
||||
} else {
|
||||
Replacement::Plain
|
||||
};
|
||||
_ => {
|
||||
let alias = get_type_alias(&ctx, &alias_instance)?;
|
||||
concrete_type = alias.ty()?;
|
||||
|
||||
replacement = if let Some(alias_generics) = alias.generic_param_list() {
|
||||
if alias_generics.generic_params().next().is_none() {
|
||||
cov_mark::hit!(no_generics_params);
|
||||
return None;
|
||||
}
|
||||
|
||||
let instance_args =
|
||||
alias_instance.syntax().descendants().find_map(ast::GenericArgList::cast);
|
||||
|
||||
Replacement::Generic {
|
||||
lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?,
|
||||
const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?,
|
||||
}
|
||||
} else {
|
||||
Replacement::Plain
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let target = alias_instance.syntax().text_range();
|
||||
|
||||
@ -752,6 +769,74 @@ mod foo {
|
||||
fn main() {
|
||||
let a: String;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_self_type() {
|
||||
check_assist(
|
||||
inline_type_alias,
|
||||
r#"
|
||||
struct Strukt;
|
||||
|
||||
impl Strukt {
|
||||
fn new() -> Self$0 {}
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
struct Strukt;
|
||||
|
||||
impl Strukt {
|
||||
fn new() -> Strukt {}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
check_assist(
|
||||
inline_type_alias,
|
||||
r#"
|
||||
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
|
||||
|
||||
impl<T, const C: usize> Strukt<'_, T, C> {
|
||||
fn new() -> Self$0 {}
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
|
||||
|
||||
impl<T, const C: usize> Strukt<'_, T, C> {
|
||||
fn new() -> Strukt<'_, T, C> {}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
check_assist(
|
||||
inline_type_alias,
|
||||
r#"
|
||||
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
|
||||
|
||||
trait Tr<'b, T> {}
|
||||
|
||||
impl<T, const C: usize> Tr<'static, u8> for Strukt<'_, T, C> {
|
||||
fn new() -> Self$0 {}
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
struct Strukt<'a, T, const C: usize>(&'a [T; C]);
|
||||
|
||||
trait Tr<'b, T> {}
|
||||
|
||||
impl<T, const C: usize> Tr<'static, u8> for Strukt<'_, T, C> {
|
||||
fn new() -> Strukt<'_, T, C> {}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
check_assist_not_applicable(
|
||||
inline_type_alias,
|
||||
r#"
|
||||
trait Tr {
|
||||
fn new() -> Self$0;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user