@@ -6,6 +6,7 @@ use ide_db::{
66 defs:: Definition ,
77 helpers:: mod_path_to_ast,
88 imports:: insert_use:: { insert_use, ImportScope , InsertUseConfig } ,
9+ path_transform:: PathTransform ,
910 search:: FileReference ,
1011 FxHashSet , RootDatabase ,
1112} ;
@@ -105,6 +106,16 @@ pub(crate) fn extract_struct_from_enum_variant(
105106 . generic_param_list ( )
106107 . and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
107108 let generics = generic_params. as_ref ( ) . map ( |generics| generics. clone_for_update ( ) ) ;
109+
110+ // resolve GenericArg in field_list to actual type
111+ let field_list = field_list. clone_for_update ( ) ;
112+ if let Some ( ( target_scope, source_scope) ) =
113+ ctx. sema . scope ( enum_ast. syntax ( ) ) . zip ( ctx. sema . scope ( field_list. syntax ( ) ) )
114+ {
115+ PathTransform :: generic_transformation ( & target_scope, & source_scope)
116+ . apply ( field_list. syntax ( ) ) ;
117+ }
118+
108119 let def =
109120 create_struct_def ( variant_name. clone ( ) , & variant, & field_list, generics, & enum_ast) ;
110121
@@ -244,8 +255,6 @@ fn create_struct_def(
244255 // for fields without any existing visibility, use visibility of enum
245256 let field_list: ast:: FieldList = match field_list {
246257 Either :: Left ( field_list) => {
247- let field_list = field_list. clone_for_update ( ) ;
248-
249258 if let Some ( vis) = & enum_vis {
250259 field_list
251260 . fields ( )
@@ -254,11 +263,9 @@ fn create_struct_def(
254263 . for_each ( |it| insert_vis ( it. syntax ( ) , vis. syntax ( ) ) ) ;
255264 }
256265
257- field_list. into ( )
266+ field_list. clone ( ) . into ( )
258267 }
259268 Either :: Right ( field_list) => {
260- let field_list = field_list. clone_for_update ( ) ;
261-
262269 if let Some ( vis) = & enum_vis {
263270 field_list
264271 . fields ( )
@@ -267,7 +274,7 @@ fn create_struct_def(
267274 . for_each ( |it| insert_vis ( it. syntax ( ) , vis. syntax ( ) ) ) ;
268275 }
269276
270- field_list. into ( )
277+ field_list. clone ( ) . into ( )
271278 }
272279 } ;
273280 field_list. reindent_to ( IndentLevel :: single ( ) ) ;
@@ -425,6 +432,59 @@ mod tests {
425432
426433 use super :: * ;
427434
435+ #[ test]
436+ fn issue_16197 ( ) {
437+ check_assist (
438+ extract_struct_from_enum_variant,
439+ r#"
440+ enum Foo {
441+ Bar $0{ node: Box<Self> },
442+ Nil,
443+ }
444+ "# ,
445+ r#"
446+ struct Bar{ node: Box<Foo> }
447+
448+ enum Foo {
449+ Bar(Bar),
450+ Nil,
451+ }
452+ "# ,
453+ ) ;
454+ check_assist (
455+ extract_struct_from_enum_variant,
456+ r#"
457+ enum Foo {
458+ Bar $0{ node: Box<Self>, a: Arc<Box<Self>> },
459+ Nil,
460+ }
461+ "# ,
462+ r#"
463+ struct Bar{ node: Box<Foo>, a: Arc<Box<Foo>> }
464+
465+ enum Foo {
466+ Bar(Bar),
467+ Nil,
468+ }
469+ "# ,
470+ ) ;
471+ check_assist (
472+ extract_struct_from_enum_variant,
473+ r#"
474+ enum Foo {
475+ Nil(Box$0<Self>, Arc<Box<Self>>),
476+ }
477+ "# ,
478+ r#"
479+ struct Nil(Box<Foo>, Arc<Box<Foo>>);
480+
481+ enum Foo {
482+ Nil(Nil),
483+ }
484+ "# ,
485+ ) ;
486+ }
487+
428488 #[ test]
429489 fn test_extract_struct_several_fields_tuple ( ) {
430490 check_assist (
0 commit comments