diff options
| author | bors <bors@rust-lang.org> | 2022-04-28 17:24:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-04-28 17:24:22 +0000 |
| commit | 339a1867f45b6bbfa0f5f5f274706b1b81b71663 (patch) | |
| tree | e92c2d727f7b4eee3dd5bb0beffd4ad89363d8f5 | |
| parent | d382e24a11c8706b201c8437894506d191691334 (diff) | |
| parent | c7027122db14317c4c4d72469e13af0292f64254 (diff) | |
| download | rust-339a1867f45b6bbfa0f5f5f274706b1b81b71663.tar.gz rust-339a1867f45b6bbfa0f5f5f274706b1b81b71663.zip | |
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
| -rw-r--r-- | crates/ide_assists/src/handlers/inline_type_alias.rs | 119 |
1 files changed, 102 insertions, 17 deletions
diff --git a/crates/ide_assists/src/handlers/inline_type_alias.rs b/crates/ide_assists/src/handlers/inline_type_alias.rs index eeb2e2e6679..bc4a07358cc 100644 --- a/crates/ide_assists/src/handlers/inline_type_alias.rs +++ b/crates/ide_assists/src/handlers/inline_type_alias.rs @@ -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, + } + + replacement = 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); + 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::Generic { + lifetime_map: LifetimeMap::new(&instance_args, &alias_generics)?, + const_and_type_map: ConstAndTypeMap::new(&instance_args, &alias_generics)?, + } + } else { + Replacement::Plain + }; } - } else { - Replacement::Plain - }; + } let target = alias_instance.syntax().text_range(); @@ -755,4 +772,72 @@ fn main() { "#, ); } + + #[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; +} +"#, + ); + } } |
