|
3 | 3 | // - "inline_alias_to_users" assist #10881.
|
4 | 4 | // - Remove unused aliases if there are no longer any users, see inline_call.rs.
|
5 | 5 |
|
6 |
| -use hir::PathResolution; |
| 6 | +use hir::{HasSource, PathResolution}; |
7 | 7 | use itertools::Itertools;
|
8 | 8 | use std::collections::HashMap;
|
9 | 9 | use syntax::{
|
@@ -41,31 +41,48 @@ use crate::{
|
41 | 41 | // }
|
42 | 42 | // ```
|
43 | 43 | 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 |
| - |
48 | 44 | enum Replacement {
|
49 | 45 | Generic { lifetime_map: LifetimeMap, const_and_type_map: ConstAndTypeMap },
|
50 | 46 | Plain,
|
51 | 47 | }
|
52 | 48 |
|
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; |
57 | 63 | }
|
| 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 | + } |
58 | 73 |
|
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); |
61 | 76 |
|
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 | + }; |
65 | 84 | }
|
66 |
| - } else { |
67 |
| - Replacement::Plain |
68 |
| - }; |
| 85 | + } |
69 | 86 |
|
70 | 87 | let target = alias_instance.syntax().text_range();
|
71 | 88 |
|
@@ -752,6 +769,74 @@ mod foo {
|
752 | 769 | fn main() {
|
753 | 770 | let a: String;
|
754 | 771 | }
|
| 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 | +} |
755 | 840 | "#,
|
756 | 841 | );
|
757 | 842 | }
|
|
0 commit comments