about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYoung-Flash <dongyang@apache.org>2024-01-03 20:07:29 +0800
committerYoung-Flash <dongyang@apache.org>2024-01-03 20:07:29 +0800
commit099c3204a2dbdc500baf1cd60c1647741c133724 (patch)
tree96ca81fb16c1d8f4ef6a2cc5c0101e307b721ea4
parent6a7d3f1c3eda7b46bb4ef7f35a9560ae0d87e97e (diff)
downloadrust-099c3204a2dbdc500baf1cd60c1647741c133724.tar.gz
rust-099c3204a2dbdc500baf1cd60c1647741c133724.zip
fix: use PathTransform to resolve GenericArg
-rw-r--r--crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs42
1 files changed, 13 insertions, 29 deletions
diff --git a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index 9f81fd932f6..074b8b79328 100644
--- a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -6,6 +6,7 @@ use ide_db::{
     defs::Definition,
     helpers::mod_path_to_ast,
     imports::insert_use::{insert_use, ImportScope, InsertUseConfig},
+    path_transform::PathTransform,
     search::FileReference,
     FxHashSet, RootDatabase,
 };
@@ -105,6 +106,16 @@ pub(crate) fn extract_struct_from_enum_variant(
                 .generic_param_list()
                 .and_then(|known_generics| extract_generic_params(&known_generics, &field_list));
             let generics = generic_params.as_ref().map(|generics| generics.clone_for_update());
+
+            // resolve GenericArg in field_list to actual type
+            let field_list = field_list.clone_for_update();
+            if let Some((target_scope, source_scope)) =
+                ctx.sema.scope(enum_ast.syntax()).zip(ctx.sema.scope(field_list.syntax()))
+            {
+                PathTransform::generic_transformation(&target_scope, &source_scope)
+                    .apply(field_list.syntax());
+            }
+
             let def =
                 create_struct_def(variant_name.clone(), &variant, &field_list, generics, &enum_ast);
 
@@ -244,31 +255,6 @@ fn create_struct_def(
     // for fields without any existing visibility, use visibility of enum
     let field_list: ast::FieldList = match field_list {
         Either::Left(field_list) => {
-            let field_list = field_list.clone_for_update();
-
-            // replace `Self` with the enum name when construct struct def
-            field_list
-                .fields()
-                .filter_map(|field| match field.ty()? {
-                    ast::Type::PathType(p) => Some(
-                        p.syntax()
-                            .descendants_with_tokens()
-                            .filter_map(|it| {
-                                if it.kind() == T![Self] {
-                                    let type_arg =
-                                        make::type_arg(make::ty(&enum_.name()?.to_string()))
-                                            .clone_for_update();
-                                    Some(ted::replace(it, type_arg.syntax()))
-                                } else {
-                                    None
-                                }
-                            })
-                            .count(),
-                    ),
-                    _ => None,
-                })
-                .count();
-
             if let Some(vis) = &enum_vis {
                 field_list
                     .fields()
@@ -277,11 +263,9 @@ fn create_struct_def(
                     .for_each(|it| insert_vis(it.syntax(), vis.syntax()));
             }
 
-            field_list.into()
+            field_list.clone().into()
         }
         Either::Right(field_list) => {
-            let field_list = field_list.clone_for_update();
-
             if let Some(vis) = &enum_vis {
                 field_list
                     .fields()
@@ -290,7 +274,7 @@ fn create_struct_def(
                     .for_each(|it| insert_vis(it.syntax(), vis.syntax()));
             }
 
-            field_list.into()
+            field_list.clone().into()
         }
     };
     field_list.reindent_to(IndentLevel::single());