From b6a1b45c2448c48214fb1a0ad3479aac6f2f9346 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 28 Apr 2022 19:20:23 +0200 Subject: [PATCH 1/2] Make "inline type alias" work for `Self` --- .../src/handlers/inline_type_alias.rs | 110 +++++++++++++++--- 1 file changed, 93 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 eeb2e2e667961..369f197456a94 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::()?; - 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::()?; + 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(); @@ -752,6 +769,65 @@ 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 Strukt<'_, T, C> { + fn new() -> Self$0 {} +} +"#, + r#" +struct Strukt<'a, T, const C: usize>(&'a [T; C]); + +impl 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 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 Tr<'static, u8> for Strukt<'_, T, C> { + fn new() -> Strukt<'_, T, C> {} +} "#, ); } From c7027122db14317c4c4d72469e13af0292f64254 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 28 Apr 2022 19:23:57 +0200 Subject: [PATCH 2/2] Add test with trait --- crates/ide_assists/src/handlers/inline_type_alias.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/ide_assists/src/handlers/inline_type_alias.rs b/crates/ide_assists/src/handlers/inline_type_alias.rs index 369f197456a94..bc4a07358cc58 100644 --- a/crates/ide_assists/src/handlers/inline_type_alias.rs +++ b/crates/ide_assists/src/handlers/inline_type_alias.rs @@ -828,6 +828,15 @@ trait Tr<'b, T> {} impl 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; +} "#, ); }